JWT(JSON Web Token)
深受开发者的喜爱,主要流程如下:token
,并将其返回给客户端token
,将其存储在 cookie
或者 localStroge
中cookie
或者header
携带该 token
token
的有效性,通过才返回响应的数据Cookie
是不允许跨域访问的,这一点对 Token
机制是不存在的,前提是传输的用户认证信息通过 HTTP
头传输Token
机制在服务端不需要存储 session
信息,因为 Token
自身包含了所有登录用户的信息,只需要在客户端的 cookie
或本地介质存储状态信息http
协议的客户端,就可以使用 token
认证。cookie
,所以采用 token
认证方式不会发生 CSRF
,所以也就无需考虑 CSRF
的防御JWT
实际上就是一个字符串,它由三部分组成:头部
、载荷
与签名
。中间用点 .
分隔成三个部分。注意 JWT
内部是没有换行的。header
由两部分组成: token
的类型 JWT
和算法名称:HMAC
、SHA256
、RSA
{
"alg": "HS256",
"typ": "JWT"
}
Payload
部分也是一个 JSON
对象,用来存放实际需要传递的数据。JWT
指定七个默认字段供选择。iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
{
"iss": "xxxxxxx",
"sub": "xxxxxxx",
"aud": "xxxxxxx",
"user": [
'username': '极客飞兔',
'gender': 1,
'nickname': '飞兔小哥'
]
}
// 其中secret 是密钥
String signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
JWT
,可以储存在 Cookie
里面, 也可以储存在 localStorage
JWT
JWT
保存在 Cookie
里面发送请求,这样不能跨域
HTTP
请求的头信息 Authorization
字段里面fetch('license/login', {
headers: {
'Authorization': 'X-TOKEN' + token
}
})
ThinkPHP6
整合 JWT
登录认证进行实战模拟composer require firebase/php-jwt
<?php
/**
* Desc: JWT认证
* Author: autofelix
* Time: 2022/07/04
*/
namespace app\services;
use app\Helper;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
class JwtService
{
protected $salt;
public function __construct()
{
//从配置信息这种或取唯一字符串,你可以随便写比如md5('token')
$this->salt = config('jwt.salt') || "autofelix";
}
// jwt生成
public function generateToken($user)
{
$data = array(
"iss" => 'autofelix', //签发者 可以为空
"aud" => 'autofelix', //面象的用户,可以为空
"iat" => Helper::getTimestamp(), //签发时间
"nbf" => Helper::getTimestamp(), //立马生效
"exp" => Helper::getTimestamp() + 7200, //token 过期时间 两小时
"user" => [ // 记录用户信息
'id' => $user->id,
'username' => $user->username,
'truename' => $user->truename,
'phone' => $user->phone,
'email' => $user->email,
'role_id' => $user->role_id
]
);
$jwt = JWT::encode($data, md5($this->salt), 'HS256');
return $jwt;
}
// jwt解密
public function chekToken($token)
{
JWT::$leeway = 60; //当前时间减去60,把时间留点余地
$decoded = JWT::decode($token, new Key(md5($this->salt), 'HS256'));
return $decoded;
}
}
<?php
declare (strict_types=1);
namespace app\controller;
use think\Request;
use app\ResponseCode;
use app\Helper;
use app\model\User as UserModel;
use app\services\JwtService;
class License
{
public function login(Request $request)
{
$data = $request->only(['username', 'password', 'code']);
// ....进行验证的相关逻辑...
$user = UserModel::where('username', $data['username'])->find();
// 验证通过生成 JWT, 返回给前端保存
$token = (new JwtService())->generateToken($user);
return json([
'code' => ResponseCode::SUCCESS,
'message' => '登录成功',
'data' => [
'token' => $token
]
]);
}
}
middleware.php
注册中间件<?php
// 全局中间件定义文件
return [
// ...其他中间件
// JWT验证
\app\middleware\Auth::class
];
<?php
declare (strict_types=1);
namespace app\middleware;
use app\ResponseCode;
use app\services\JwtService;
class Auth
{
private $router_white_list = ['login'];
public function handle($request, \Closure $next)
{
if (!in_array($request->pathinfo(), $this->router_white_list)) {
$token = $request->header('token');
try {
// jwt 验证
$jwt = (new JwtService())->chekToken($token);
} catch (\Throwable $e) {
return json([
'code' => ResponseCode::ERROR,
'msg' => 'Token验证失败'
]);
}
$request->user = $jwt->user;
}
return $next($request);
}
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。