Cet article est basé sur l'analyse et l'écriture du code du module Auth de la version Laravel 5.4
Composition du module
Le module Auth est fonctionnellement divisé en deux ; parties : authentification des utilisateurs et gestion des autorisations En termes de composition des fichiers, le répertoire IlluminateAuthPasswords est un petit module pour la réinitialisation des mots de passe ou le traitement des mots de passe oubliés. IlluminateAuth est un module responsable de l'authentification des utilisateurs et de la gestion des autorisations. , réinitialisation des mots de passe, etc. Implémentation logique ; La figure suivante montre la relation entre les différents fichiers du module Auth et donne une brève explication
Authentification de l'utilisateur
HTTP lui-même Il est apatride, généralement en cours d'interaction avec le système, l'identification du compte ou du jeton est utilisée pour déterminer l'utilisateur authentifié Interprétation du fichier de configurationreturn [ 'defaults' => [ 'guard' => 'web', ... ], 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], ], ], ];Comprendre de bas en haut ;
providers est une interface qui fournit des données utilisateur, et l'objet pilote et l'objet cible doivent être marqués ici, le nom clé des utilisateurs est le nom d'un ensemble de fournisseurs, pilotés par ; éloquent et modal est AppUser::class;
la partie gardes est destinée à configurer la partie gestion de l'authentification ; il existe deux méthodes d'authentification, l'une est appelée Web et l'autre est l'authentification Web basée sur l'interaction de session ; , l'ID utilisateur est obtenu en fonction du sessionId et l'utilisateur est interrogé dans le fournisseur d'utilisateurs ; l'authentification API est basée sur le jeton. L'interaction avec la valeur utilise également le fournisseur d'utilisateurs
l'élément par défaut indique que l'authentification Web est utilisée par ; par défaut ;
AuthentificationInformations d'authentification de liaison de session :
// $credentials数组存放认证条件,比如邮箱或者用户名、密码 // $remember 表示是否要记住,生成 `remember_token` public function attempt(array $credentials = [], $remember = false) public function login(AuthenticatableContract $user, $remember = false) public function loginUsingId($id, $remember = false)
Authentification de base HTTP, les informations d'authentification sont placées dans l'en-tête de la requête ; accessible via sessionId ;
public function basic($field = 'email', $extraConditions = [])
n'est authentifié que dans la session en cours, et les informations d'authentification ne sont pas enregistrées dans la session :
public function once(array $credentials = []) public function onceUsingId($id) public function onceBasic($field = 'email', $extraConditions = [])
Pendant le processus d'authentification (y compris l'inscription, le mot de passe oublié), le Les événements définis sont les suivants :
Tentative de vérification de l'événement
Événement de réussite de la vérification authentifiée
Échec de l'événement d'échec de la vérification
Verrouillage Le nombre d'échecs dépasse le limite, verrouillez à nouveau la demande d'accès à l'événement
Événement Logi appelé lors d'une connexion réussie via 'remember_token'
Événement de sortie d'utilisateur de déconnexion
Événement d'inscription d'utilisateur enregistré
Il existe d'autres méthodes d'authentification :
Vérifiez s'il existe un utilisateur authentifié : Auth::check()
Obtenez l'utilisateur authentifié actuel : Auth ::user()
Quitter le système : Auth::logout()
Traitement des mots de passe
Interprétation de la configuration
return [ 'defaults' => [ 'passwords' => 'users', ... ], 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], ], ]
Regardez la configuration de bas en haut ;
Le tableau des mots de passe est la configuration permettant de réinitialiser le mot de passe ; les utilisateurs sont l'alias du schéma de configuration, qui contient trois éléments : le fournisseur (le schéma qui fournit les utilisateurs, qui est le tableau des fournisseurs ci-dessus), la table (la table qui stocke le réinitialiser le jeton de mot de passe) ), expirer (délai d'expiration du jeton)
l'élément par défaut définira le schéma de réinitialisation des mots de passe par défaut
Appel et mise en œuvre de la réinitialisation des mots de passeVoyons d'abord comment la fonction de réinitialisation de mot de passe de Laravel est implémentée :
public function reset(array $credentials, Closure $callback) { // 验证用户名、密码和 token 是否有效 $user = $this->validateReset($credentials); if (! $user instanceof CanResetPasswordContract) { return $user; } $password = $credentials['password']; // 回调函数执行修改密码,及持久化存储 $callback($user, $password); // 删除重置密码时持久化存储保存的 token $this->tokens->delete($user); return static::PASSWORD_RESET; }Regardez ensuite comment le module de réinitialisation de mot de passe encapsulé par le module FoundationAuth est appelé :
// 暴露的重置密码 API public function reset(Request $request) { // 验证请求参数 token、email、password、password_confirmation $this->validate($request, $this->rules(), $this->validationErrorMessages()); // 调用重置密码的方法,第二个参数是回调,做一些持久化存储工作 $response = $this->broker()->reset( $this->credentials($request), function ($user, $password) { $this->resetPassword($user, $password); } ); // 封装 Response return $response == Password::PASSWORD_RESET ? $this->sendResetResponse($response) : $this->sendResetFailedResponse($request, $response); } // 获取重置密码时的请求参数 protected function credentials(Request $request) { return $request->only( 'email', 'password', 'password_confirmation', 'token' ); } // 重置密码的真实性验证后,进行的持久化工作 protected function resetPassword($user, $password) { // 修改后的密码、重新生成 remember_token $user->forceFill([ 'password' => bcrypt($password), 'remember_token' => Str::random(60), ])->save(); // session 中的用户信息也进行重新赋值 $this->guard()->login($user); }« Mot de passe oublié => Le processus général de "Envoyer un e-mail => Réinitialiser le mot de passe" est le suivant : Cliquez sur "Mot de passe oublié", accédez à la page "Mot de passe oublié" via la configuration du routage, et il y a un champ "E-mail à envoyer " sur la page. Remplissez; Vérifiez si "l'email à envoyer" existe dans la base de données. S'il existe, un email de réinitialisation du mot de passe sera envoyé à l'adresse email; Il y a un lien dans l'e-mail de réinitialisation du mot de passe (après avoir cliqué, le jeton sera transféré vers la page de changement de mot de passe), et la base de données enregistrera la valeur cryptée par hachage de ce jeton Après avoir rempli les trois ; les champs « E-mail », « Mot de passe » et « Confirmer le mot de passe », le jeton accède à l'API de réinitialisation du mot de passe. La page d'accueil détermine les trois champs d'e-mail, de mot de passe et de mot de passe de confirmation, puis vérifie si le jeton est valide ; , la réinitialisation est réussie ;
Gestion des autorisations
La gestion des autorisations est maintenue par les capacités, une variable tableau maintenue dans l'espace mémoire : $abilities = array(
'定义的动作名,比如以路由的 as 名(common.dashboard.list)' => function($user) {
// 方法的参数,第一位是 $user, 当前 user, 后面的参数可以自行决定
return true; // 返回 true 意味有权限, false 意味没有权限
},
......
);
Mais seule l'utilisation de $abilities utilisera la partie définie du code pour rassembler ce qui est trop lourd, donc il y a l'émergence d'une classe de stratégie politique
la classe de politique politique définit la relation correspondante entre ; un groupe d'entités et de classes d'autorisation d'entité. Par exemple, prenons l'article comme exemple :
Il existe une classe d'entité modale appelée Post, qui peut être utilisée pour cela. La classe d'entité définit une classe d'autorisation PostPolicy, et définit certaines actions comme noms de méthodes dans cette classe d'autorisation ;
class PostPolicy { // update 权限,文章作者才可以修改 public function update(User $user, Post $post) { return $user->id === $post->user_id; } }
puis l'enregistre dans le ServiceProvider, afin que le système sache que si la classe que vous souhaitez vérifier est un objet Post, ajoutez votre étant donné le nom de l'action. , le système trouvera la méthode correspondante de la classe PostPolicy ; comment appeler
protected $policies = [ Post::class => PostPolicy::class, ];
?
Pour les autorisations définies dans le tableau des capacités :
Si l'utilisateur actuel dispose de l'autorisation common.dashboard.list : Gate::allows('common.dashboard.list')
Si l'utilisateur actuel dispose des autorisations common.dashboard.list :! Gate::denies('common.dashboard.list')
Si l'utilisateur actuel dispose des autorisations common.dashboard.list : $request-> ;user() ->can('common.dashboard.list')
Si l'utilisateur actuel dispose de l'autorisation common.dashboard.list :! $request->user()->cannot(' common.dashboard.list')
指定用户是否具备common.dashboard.list权限:Gate::forUser($user)->allows('common.dashboard.list')
对于policy策略类调用的权限:
当前用户是否可以修改文章(Gate 调用):Gate::allows('update', $post)
当前用户是否可以修改文章(user 调用):$user->can('update', $post)
当前用户是否可以修改文章(用帮助函数):policy($post)->update($user, $post)
当前用户是否可以修改文章(Controller 类方法中调用):$this->authorize('update', $post);
当前用户是否可以修改文章(Controller 类同名方法中调用):$this->authorize($post);
指定用户是否可以修改文章(Controller 类方法中调用):$this->authorizeForUser($user, 'update', $post);
有用的技巧
获取当前系统注册的权限,包括两部分abilities和policies数组内容,代码如下:
$gate = app(\Illuminate\Contracts\Auth\Access\Gate::class); $reflection_gate = new ReflectionClass($gate); $policies = $reflection_gate->getProperty('policies'); $policies->setAccessible(true); // 获取当前注册的 policies 数组 dump($policies->getValue($gate)); $abilities = $reflection_gate->getProperty('abilities'); $abilities->setAccessible(true); // 获取当前注册的 abilities 数组 dump($abilities->getValue($gate));
推荐教程:《Laravel教程》
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!