应用的身份认证一般包含两种:web 浏览器认证
和API 认证
基于 web 浏览器的身份验证:常见于前后端混合开发的项目,php混合html模版;使用session
cookie
完成身份验证。现在很少见了
基于 api 的身份验证:常见于前后端分离的项目,一套api同时给前端,Android,iOS提供服务;使用token
完成身份验证。也是当下最流行的开发模式
在其核心,Laravel 的用户认证是由「看守器」和「提供器」。看守器定义如何对每个请求的用户进行身份验证。例如,Laravel 附带了一个 session 守护程序,它使用 session 存储和 cookie 来维护状态。 提供器定义如何从持久存储中检索用户。Laravel 支持使用 Eloquent 和数据库查询生成器检索用户。不仅如此,你甚至可以根据应用程序的需要自由定制其他提供程序。
下面介绍都是基于 api 的身份验证
手动验证用户
代码语言:javascript复制 $credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('dashboard');
}
Auth::attempt
方法会做两件事:
- 查询用户:除了password以外的字段都会作为查询条件
- 比对密码:明文密码即可,因为框架将该值与数据库中的散列密码进行比较之前会自动加密
以上两个操作都成功才会返回true
源码位置:
代码语言:javascript复制vendor/laravel/framework/src/Illuminate/Contracts/Auth/StatefulGuard.php
public function attempt(array $credentials = [], $remember = false);
访问特定的看守器实例
传递给 guard 方法的名称应存在 auth.php 配置文件中
代码语言:javascript复制if (Auth::guard('admin')->attempt($credentials)) {
// ...
}
记住用户
users 表必须包含字符串 remember_token 列
过时的功能。。
其他认证方法
代码语言:javascript复制use IlluminateSupportFacadesAuth;
Auth::login($user);
Auth::login($user, $remember = true);
Auth::guard('admin')->login($user);
Auth::loginUsingId(1);
Auth::loginUsingId(1, $remember = true);
if (Auth::once($credentials)) {
//
}
HTTP Basic 用户认证
不常用,再议。。
退出登录
要在应用程序中手动注销用户,可以使用 Auth facade 提供的 logout 方法。
代码语言:javascript复制Auth::logout();
添加自定义的看守器
你可以使用 Auth facade 上的 extend 方法定义自己的身份验证看守器。你应该在 服务提供器 中调用 extend 方法。 由于 Laravel 已经附带了 AuthServiceProvider,因此我们可以将代码放置在该提供程序中:
代码语言:javascript复制<?php
namespace AppProviders;
use AppServicesAuthJwtGuard;
use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;
use IlluminateSupportFacadesAuth;
class AuthServiceProvider extends ServiceProvider
{
/**
* 注册任意的身份验证和身份授权的服务
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::extend('jwt', function ($app, $name, array $config) {
// 返回 IlluminateContractsAuthGuard 的实例 ...
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
}
正如你在上面的示例中所看到的,传递给 extend 方法的回调应该返回 IlluminateContractsAuthGuard 的实例。此接口包含一些方法,你需要实现这些方法来定义自定义看守器。一旦你的自定义看守器被定义,你就可以在你的应用程序 auth.php 配置文件的 guards 配置中引用该看守器:
代码语言:javascript复制'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
闭包请求看守器
实现自定义的、基于 HTTP 请求的身份验证系统的最简单方法是使用 Auth::viaRequest 方法。此方法允许你使用单个闭包快速定义身份验证过程。
首先,请在您的 AuthServiceProvider 的 boot 方法中调用 Auth::viaRequest 方法。 VIASRequest 方法接受身份验证驱动程序名称作为其第一个参数。此名称可以是描述自定义看守器的任何字符串。传递给方法的第二个参数应该是一个闭包,该闭包接收传入的 HTTP 请求并返回用户实例,或者,如果验证失败返回 null:
代码语言:javascript复制use AppModelsUser;
use IlluminateHttpRequest;
use IlluminateSupportFacadesAuth;
/**
* 注册任何应用程序验证 / 授权服务。
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::viaRequest('custom-token', function (Request $request) {
return User::where('token', $request->token)->first();
});
}
一旦你定义自定义身份验证驱动程序,就可以将其配置为 auth.php 配置文件:
代码语言:javascript复制'guards' => [
'api' => [
'driver' => 'custom-token',
],
],
添加自定义的用户提供器
如果不使用传统的关系数据库来存储用户,则需要使用自己的身份验证用户提供程序来扩展 Laravel 。 我们将使用 Auth facade 上的 provider 方法来定义自定义用户提供器。提供器解析器应返回 IlluminateContractsAuthUserProvider 的实例:
代码语言:javascript复制<?php
namespace AppProviders;
use AppExtensionsMongoUserProvider;
use IlluminateFoundationSupportProvidersAuthServiceProvider as ServiceProvider;
use IlluminateSupportFacadesAuth;
class AuthServiceProvider extends ServiceProvider
{
/**
* 注册任何应用程序验证 / 授权服务。
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::provider('mongo', function ($app, array $config) {
// 返回 illighteContractsAuthUserProvider 的实例...
return new MongoUserProvider($app->make('mongo.connection'));
});
}
}
使用 provider 方法注册提供程序后,你可以在 auth.php 配置文件中切换到新的提供程序。 首先,定义一个使用新驱动程序的 provider :
代码语言:javascript复制'providers' => [
'users' => [
'driver' => 'mongo',
],
],
用户提供器契约
建议看原文档
Authenticatable 契约
建议看原文档
参考
https://learnku.com/docs/laravel/9.x/authentication/12239