En bref, est-il possible de s'authentifier sans base de données (à la place, en utilisant User Provider)?
J'ai vu des articles sur comment s'authentifier sans mot de passe , mais serait-il possible de s'authentifier sansDB?
Voici ce que j'ai essayé de réaliser ...
Ask the user to submit a PIN
Compare the PIN with a value within .env
If the PIN is correct, authenticate the user
Il semble possible de s'authentifier sans un SGBDR classique en introduisant un fournisseur d'utilisateur.
Cependant, la documentation ne semble pas décrire comment le fournisseur d'utilisateurs devrait ressembler.
Voici des extraits de mon code (enfin, j'ai simplement imité le doc) ...
class AuthServiceProvider extends ServiceProvider {
public function boot()
{
$this->registerPolicies();
Auth::provider('myUser', function ($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new MyUserProvider($app->make('myUser'));
});
}
}
Dans auth.php
...
'providers' => [
'users' => [
'driver' => 'myUser',
],
],
Maintenant, je ne sais pas comment procéder.
Donc, j'aimerais savoir ...
A quoi devrait ressembler le user provider
s'il est possible d'authentifier les utilisateurs avec env()
en premier lieu
Tout conseil sera apprécié.
Merci à tous, mais il y avait une solution beaucoup plus simple ... qui consiste à utiliser session()
.
Dans le contrôleur,
public function login(Request $request)
{
if ($request->input('pin') === env('PIN')) {
$request->session()->put('authenticated', time());
return redirect()->intended('success');
}
return view('auth.login', [
'message' => 'Provided PIN is invalid. ',
]);
//Or, you can throw an exception here.
}
L'itinéraire ressemble à,
Route::group(['middleware' => ['web', 'custom_auth']], function () {
Route::get('/success', 'Controller@success')->name('success');
});
Le custom_auth
ressemblera,
public function handle($request, Closure $next)
{
if (!empty(session('authenticated'))) {
$request->session()->put('authenticated', time());
return $next($request);
}
return redirect('/login');
}
J'espère que cela aidera quelqu'un.
Créez votre propre interface Guard
en ignorant UserProvider
. Je l'ai adopté dans mon projet et ça fonctionne bien.
PinGuard.php
<?php
declare(strict_types=1);
namespace App\Auth\Guards;
use App\User;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
/**
* Class PinGuard
*/
class PinGuard implements Guard
{
/**
* @var null|Authenticatable|User
*/
protected $user;
/**
* @var Request
*/
protected $request;
/**
* OpenAPIGuard constructor.
*
* @param Request $request
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Check whether user is logged in.
*
* @return bool
*/
public function check(): bool
{
return (bool)$this->user();
}
/**
* Check whether user is not logged in.
*
* @return bool
*/
public function guest(): bool
{
return !$this->check();
}
/**
* Return user id or null.
*
* @return null|int
*/
public function id(): ?int
{
$user = $this->user();
return $user->id ?? null;
}
/**
* Manually set user as logged in.
*
* @param null|\App\User|\Illuminate\Contracts\Auth\Authenticatable $user
* @return $this
*/
public function setUser(?Authenticatable $user): self
{
$this->user = $user;
return $this;
}
/**
* @param array $credentials
* @return bool
*/
public function validate(array $credentials = []): bool
{
throw new \BadMethodCallException('Unexpected method call');
}
/**
* Return user or throw AuthenticationException.
*
* @throws AuthenticationException
* @return \App\User
*/
public function authenticate(): User
{
$user = $this->user();
if ($user instanceof User) {
return $user;
}
throw new AuthenticationException();
}
/**
* Return cached user or newly authenticate user.
*
* @return null|\App\User|\Illuminate\Contracts\Auth\Authenticatable
*/
public function user(): ?User
{
return $this->user ?: $this->signInWithPin();
}
/**
* Sign in using requested PIN.
*
* @return null|User
*/
protected function signInWithPin(): ?User
{
// Implement your logic here
// Return User on success, or return null on failure
}
/**
* Logout user.
*/
public function logout(): void
{
if ($this->user) {
$this->setUser(null);
}
}
}
NoRememberTokenAuthenticatable.php
User
devrait mélanger ce trait.
<?php
declare(strict_types=1);
namespace App\Auth;
use Illuminate\Database\Eloquent\Model;
/**
* Trait NoRememberTokenAuthenticatable
*
* @mixin Model
*/
trait NoRememberTokenAuthenticatable
{
/**
* Get the name of the unique identifier for the user.
*
* @return string
*/
public function getAuthIdentifierName()
{
return 'id';
}
/**
* Get the unique identifier for the user.
*
* @return mixed
*/
public function getAuthIdentifier()
{
return $this->id;
}
/**
* Get the password for the user.
*
* @return string
* @codeCoverageIgnore
*/
public function getAuthPassword()
{
throw new \BadMethodCallException('Unexpected method call');
}
/**
* Get the token value for the "remember me" session.
*
* @return string
* @codeCoverageIgnore
*/
public function getRememberToken()
{
throw new \BadMethodCallException('Unexpected method call');
}
/**
* Set the token value for the "remember me" session.
*
* @param string $value
* @codeCoverageIgnore
*/
public function setRememberToken($value)
{
throw new \BadMethodCallException('Unexpected method call');
}
/**
* Get the column name for the "remember me" token.
*
* @return string
* @codeCoverageIgnore
*/
public function getRememberTokenName()
{
throw new \BadMethodCallException('Unexpected method call');
}
}
AuthServiceProvider.php
<?php
declare(strict_types=1);
namespace App\Providers;
use App\Auth\Guards\PinGuard;
use Illuminate\Container\Container;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [];
/**
* Register any authentication / authorization services.
*/
public function boot()
{
Auth::extend('pin', function (Container $app) {
return new PinGuard($app['request']);
});
$this->registerPolicies();
}
}
config/auth.php
Vous devriez commenter la plupart d'entre eux.
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
// 'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'pin',
],
// 'api' => [
// 'driver' => 'session',
// 'provider' => 'users',
// ],
// 'web' => [
// 'driver' => 'session',
// 'provider' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
// 'users' => [
// 'driver' => 'eloquent',
// 'model' => App\User::class,
// ],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
// 'passwords' => [
// 'users' => [
// 'provider' => 'users',
// 'table' => 'password_resets',
// 'expire' => 60,
// ],
// ],
];
Si vous savez qui est l'utilisateur (IE: possédez déjà une instance de $ utilisateur), vous pouvez simplement vous connecter sans utiliser de protections, comme indiqué dans la documentation.
Auth::login($user);
Je passerais dans une instance d'utilisateur au lieu de $ email/$ mot de passe à votre fonction
$user = User::whereEmail($email)->first();
$class->login($user);
et ensuite dans votre classe
public static function Login(User $user)
{
// ...
if(substr ( $result, 0, 3 ) == '+OK')
Auth::login($user);
return true; //user will be logged in and then redirect
else
return false;
}