前言
距上次使用Laravel + jwt 已经好久了,依稀记得当时很惨烈,各种文档不全看不懂,最后照着网上搜来的一个教程一步一步不知所云的才勉勉强强上线,那会用的还是laravel 5,这次弥补一下遗憾,重新自己挖坑 填坑来一次!
Ps:最近感受到了composer管理包带来的便利性,开始多多加强composer的使用和学习
准备工作
- laravel/laravel:6.8
tymon/jwt-auth:1.0.0-rc.5
- 这个版本支持laravel 6
安装
在项目中直接require
即可
composer require tymon/jwt-auth:1.0.0-rc.5
Composer 安装时内存不足失败
俩种选择,换一个内存大的环境对项目进行安装,比如本地
或者增加环境的虚拟内存大小
/bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024
/sbin/mkswap /var/swap.1
/sbin/swapon /var/swap.1
以上操作需要root权限
如果你之前已经有swap交换文件了,执行以上步骤后会自动累加
重启后新增的交换文件不会自动挂载,需要手动执行以下俩步操作或者放在开机脚本内
/sbin/mkswap /var/swap.1
/sbin/swapon /var/swap.1
相关文档:
https://jwt-auth.readthedocs.io/en/develop/laravel-installation/
https://learnku.com/articles/10885/full-use-of-jwt
调试Jwt
第一步:安装好后,生成一个key
php artisan jwt:secret
第二步:把配置文件迁移到 config/ 下
配置挪出来,保证一致性,原位置在vender中,会被gitignore忽略
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
第三步:修改用户模型
Jwt验证是和用户的模型相关联的,需要修改你的用户模型
引入 JWTSubject
,并让模型去实现 JWTSubject
这里删除了邮箱验证 MustVerifyEmail
第四步:添加Facade (可选)
在laravel
的配置文件 config/app.php
中的aliases
下添加
也可以使用laravel 的辅助函数 auth()
, 这里我不添加
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
'JWTFactory' => Tymon\JWTAuth\Facades\JWTFactory::class,
第五步:修改 auth.php
把api
的driver
,更换成我们要使用的jwt
provider
选择用户模型的提供者
上图提到的提供者在下面定义,把我们修改好的用户模型绑定到model
上
以下来自官方机翻
在这里,我们告诉api后卫使用jwt驱动程序,并将api后卫设置为默认值。
现在,我们可以使用Laravel内置的Auth系统,通过jwt-auth进行幕后工作!
到此,JWT 配置完了,看看怎么使用吧!
使用 JWT
第一步 jwt的作用
其实状态无非就是以下几种:
- 生成
token
:把用户和token绑定在一起 => 用户的“密码” - 验证
token
:ok => “登录”成功 - 将
token
过期 :把用户“密码”删了 token
过期了:“登录”超时- 刷新
token
:把“密码”的过期时间延期
第二步 token的使用
因为没有添加 jwt
的 Facades
, 下面全部使用laravel的函数 auth()
如果 guard
的默认值是 api
(我们前俩步已经改好了),我们就可以直接使用auth()
如需指定其他guard
设备,使用auth('qita')
括号内指定即可
并且部分方法还可方便的直接使用静态 auth::id()
. 以下 auth::
全部可用 auth()->
替换
A. 生成token:
- 使用用户模型生成
$token = auth()->login($userModel); - 使用模型的用户主键 id 生成
$token = auth()-> tokenById('id'); - 验证账号密码然后生成
$token = auth()-> attempt(['账号','密码']); - 生成时携带载荷
$claims = ['mes'=>'lihai','code'=>'1001'];
$token = auth()->claims($claims)->login($user);
B. 验证token:
token的验证是基于中间件的自动验证,可选jwt的中间件或laravel的中间件
JWT中间件:
引用自learnku@skyArony 第一二个功能一样,但是第二个不会抛出错误,第三四个功能一样,没什么区别。
protected $middlewareAliases = [
'jwt.auth' => Authenticate::class,
'jwt.check' => Check::class,
'jwt.refresh' => RefreshToken::class,
'jwt.renew' => AuthenticateAndRenew::class,
];
laravel中间件 auth:api
:
有一点需要注意,需要到./Exceptions/Handler.php
重写以下方法,自定义验证失败操作(默认验证失败跳到login
路由)
public function unauthenticated($request, $exception)
{
return $request->expectsJson()
? response()->json(['message' => 'Unauthenticated.'], 401)
: response()->json(['mes'=>'token验证失败','code'=>'96104'],401);
}
中间件也需设置 .../Middleware/Authenticate.php
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
// return route('login');
return null;
}
}
C. 使用Token
使用其验证
加到网址中 => 相当于明文
?token=token
加到 header中 => 在 https下是加密的
Authorization:Bearer token
使用其解析
获取 token中的 user对象
$user = auth::user();
获取 token中的 userid
$userid = auth::id();
解析 token的信息 (如果设置了载荷就会解析出来)
$info = auth::payload()->toarray();
array:8 [
"iss" => "http://wb.com/api/login"
"iat" => 1577167749 # 签发时间
"exp" => 1577171349 # 过期时间
"nbf" => 1577167749 # 生效时间
"jti" => "Kf4000hFaYYNMC7x"
"sub" => 7
"prv" => "8e744acf675a27367db01824c52901256f6ba54a"
"niubi" => "hehe" # 载荷
]
D. 删除Token
# 退出登录
auth::logout();
# 加到黑名单
auth()->invalidate()
E. 刷新Token
# 刷新token 拿到新的,旧的失效(可设置宽限时间)
$token = auth::refresh();
第三步 写一个token的基本控制器
php artisan make:controller AuthController