Do I have to create a guard class?
Not exactly. As you are instantiating a new object you could use one of the guard drivers Laravel ships with.
As you seem to be willing to use the same session-based login you could add this at your package's Service Provider boot method:
<?php
namespace JeroenvanRensen\MoonPHP;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Contracts\Hashing\Hasher;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;
class MoonServiceProvider extends ServiceProvider
{
public function register()
{
// some code
}
public function boot()
{
// Register new user provider with AuthManager
Auth::provider('moon', function ($app, $config) {
// change this to your Admin model's FQCN
$model = \JeroenvanRensen\MoonPHP\Models\Admin::class;
return new EloquentUserProvider($app->make(Hasher::class), $model);
});
// Register new guard driver with AuthManager
Auth::extend('moon', function ($app, $name, $config) {
// as you are doing a package, we will override
// the config that usually would come
// from `./auth/config.php
$config = [
'provider' => 'moon',
];
return Auth::createSessionDriver($name, $config);
});
}
}
This will register:
- A new User Provider using the
EloquentUserProviderdriver, but bound to the model your package provides. - A new Guard Driver, using Laravel's
SessionGuard, but configured using the new user provider just created.
If your IDE complaint at this line:
return Auth::createSessionDriver($name, $config);
Don't worry, the createSessionDriver() method is not listed in the Auth façade's doc-blocks, so IDE won't find it. But its a public method in the AuthManager class, which the Auth façade provides, so Laravel will find it.
Then in your controller you have a minor misconception:
<?php
namespace JeroenvanRensen\MoonPHP\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function show()
{
return view('moon::auth.login');
}
public function store()
{
// You were doing nothing with the result of this call
$guard = Auth::guard('moon');
// Use the guard retrieved above
if ($guard->attempt(['email' => request('email'), 'password' => request('password')])) {
return redirect('/admin');
}
return back()->withInput(request()->only('email', 'remember'));
}
}
I added some comments to highlight what was missing.
But basically, calling Auth::attempt(...) without a guard, would use the default guard configured in the userś project ./config/auth.php file, it generally is the web guard.
A more concise version of your controller, that maybe will make things more clear would be this:
<?php
namespace JeroenvanRensen\MoonPHP\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function show()
{
return view('moon::auth.login');
}
public function store()
{
// Retrieve the wanted guard from Auth
if (Auth::guard('moon')->attempt(['email' => request('email'), 'password' => request('password')])) {
return redirect('/admin');
}
return back()->withInput(request()->only('email', 'remember'));
}
}
This should do it.
As an additional remark, I see two main problems with you controller:
- It extends the
Controllerclass from you package user's project. Your package should avoid depending on user code, and in this case there is no benefit extending from the user project. - You are not doing any input validation.
Below is a suggestion addressing both remarks:
<?php
namespace JeroenvanRensen\MoonPHP\Http\Controllers\Auth;
use Illuminate\Support\Facades\Auth;
// Not extending code from the App namespace anymore
class LoginController
{
public function show()
{
return view('moon::auth.login');
}
public function store()
{
// Added validation, the validated fields as
// an array is the return value
$credentials = request()->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::guard('moon')->attempt($credentials, request('remember', false))) {
return redirect('/admin');
}
return back()->withInput(request()->only(['email', 'remember']));
}
}
Hope it makes thing clearer and helps you.