miladrahimi / larajwt
Laravel项目的JWT认证工具和守卫
Requires
- php: >=7.0
- laravel/framework: ^5.5
- lcobucci/jwt: ^3.2
Requires (Dev)
- mockery/mockery: ~1.0
- orchestra/testbench: ^3.5
README
Laravel JWT守卫和认证工具
此包已不再维护。您可以改用 laravel/passport 包。或者,您也可以使用 miladrahimi/php-jwt 创建自定义jwt守卫。
文档
概述
LaraJwt是一个用于生成JWT(基于JSON Web Token)并为Laravel应用提供JWT守卫的Laravel包。
安装
使用Composer添加此包
composer require miladrahimi/larajwt:2.*
然后运行以下命令以在您的Laravel配置目录中生成jwt.php
(包配置)
php artisan vendor:publish --tag=larajwt-config
安装说明
-
包服务提供者将由Laravel包发现自动发现。
-
JwtAuth
别名将由MiladRahimi\LaraJwt\Facades\JwtAuth
自动注册。
配置
要配置包,请打开您的laravel配置目录中的jwt.php
文件。此文件包含以下项目
key
:用于签名令牌的密钥,如果留空,则使用项目密钥。ttl
:令牌有效的时间,令牌将在该时间后过期(以秒为单位)issuer
:发行者声明audience
:受众声明model_safe
:如果您使用LaraJwt对不同的模型使用不同的认证,则将其设置为true,它确保令牌属于守卫中定义的相关模型。
从用户生成JWT
使用以下方法从用户或其他任何可验证实体(模型)生成JWT
$jwt = JwtAuth::generateToken($user);
例如,您可以在登录过程中这样从用户生成JWT
$credential = [
'email' => $request->input('email'),
'password' => $request->input('password'),
];
if(Auth::guard('api')->attempt($credential)) {
$user = Auth::guard('api')->user();
$jwt = JwtAuth::generateToken($user);
// Return successfull sign in response with the generated jwt.
} else {
// Return response for failed attempt...
}
如果您想将更多信息(如角色)存储在令牌中,您可以通过这种方式将这些信息传递给该方法
$customClaims = ['role' => 'admin', 'foo' => 'bar'];
$jwt = JwtAuth::generateToken($user, $customClaims);
守卫
在您的config/auth.php
中添加所需数量的守卫,并使用jwt
驱动程序,如下例所示
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
受保护路由
配置config/auth.php
中的守卫后,您可以使用定义的守卫保护路由。
在我们的示例中,我们可以这样保护路由
Route::group(['middleware' => 'auth:api'], function () {
// Routes...
});
- 您的客户端必须在请求中发送标头
Authorization: Bearer <jwt>
。
受保护用户
要检索应用程序中的当前用户及其信息(例如控制器),您可以这样做
// To get current user
$user = Auth::guard('api')->user();
$user = Auth::guard('api')->getUser();
// To get current user id
$user = Auth::guard('api')->id();
// Is current user guest
$user = Auth::guard('api')->guest();
// To get current token
$jwt = Auth::guard('api')->getToken();
// To get current token claims
$claims = Auth::guard('api')->getClaims();
// To get a sepcific claim from current token
$role = Auth::guard('api')->getClaim('role');
// Logout current user (JWT will be cached in blacklist and NOT valid in next requests).
Auth::guard('api')->logout();
// Logout current user (but it will be VALID next reuqests).
// It clears caches so user will be fetched and filters will be executed again in next request.
Auth::guard('api')->logout(false);
由于LaraJwt缓存用户获取,它可以在不接触数据库的情况下验证用户。
手动检索用户
您可能需要手动从生成的JWT中检索用户,别担心!只需按照这种方式操作即可
$user = JwtAuth::retrieveUser($jwt);
它使用默认的用户提供者来检索用户,如果您使用的是不同的提供者,可以将它作为第二个参数传递给方法,如下所示
$admin = JwtAuth::retrieveUser($jwt, 'admin');
手动检索JWT声明
您甚至可以进一步手动检索JWT声明,它也已经考虑到了这一点。
$claims = JwtAuth::retrieveClaims($jwt);
所述方法返回以下结构的声明关联数组
[
'sub' => '666',
'iss' => 'Your app name',
'aud' => 'Your app audience',
// ...
]
缓存
LaraJwt缓存检索用户的过程,因此,在第一次成功认证后,它会记住jwt,直到配置中设置的ttl,您可以清除此缓存以强制LaraJwt重新运行过滤器或从数据库中重新获取用户模型,为此您可以使用此方法
JwtAuth::clearCache($user);
您可以将用户模型(Authenticable)或其主键传递给clearCache
方法。
过滤器
过滤器是可运行的闭包,将在解析令牌和检索用户模型之后被调用。
例如,如果您为用户考虑了布尔属性is_active
,您可能希望在认证后检查其值,如果它是false,则引发异常或以某种方式更改LaraJwt的正常流程,使其看起来认证失败。
您可以注册尽可能多的过滤器,LaraJwt将在认证后按顺序运行它们。
AuthServiceProvider似乎是一个注册钩子的好地方。
class AuthServiceProvider extends ServiceProvider
{
// ...
public function boot()
{
// ...
$jwtAuth = $this->app->make(JwtAuthInterface::class);
// Check if user is active or not
$jwtAuth->registerFilter(function (User $user) {
if ($user->is_active == true) {
return $user;
} else {
return null;
}
});
}
}
registerFilter
接受一个闭包作为参数,以获取已认证的用户,如果没有问题,它应该返回用户,如果想要使认证失败,则可以返回null。
登出和JWT失效
如上例所示,您可以使用以下方法登出用户
Auth::guard('api')->logout();
它接受一个布尔参数,默认为true,将jwt放入缓存的黑名单中,因此令牌在下一个请求中不会有效,但您也可以传递false以使它只登出当前用户并清除缓存。
您还可以通过JwtAuth
外观和jti
声明以这种方式使令牌失效
JwtAuth::invalidate($jti);
异常
Exception Class: LaraJwtConfiguringException
Exception Message: LaraJwt config not found.
如果您尚未发布包配置(如安装部分所述),则会抛出此异常。
JWT与存储令牌
您可能会考虑简单的数据库存储令牌作为JWT的替代方案用于认证,因此我们为您提供了差异和比较。
缺点
- 更多的HTTP开销,生成的令牌较长。
- 强制登出更复杂且棘手(LaraJwt为您处理它)。
优点
- 不需要数据库列来存储生成的令牌。
- 如果您只需要用户ID,则无需接触数据库。
- 如果您缓存用户检索(LaraJwt为您这样做),则对数据库的接触更少。
贡献
任何贡献都将受到赞赏 :D
许可
此包在MIT许可证下发布。