大家好,又见面了,我是你们的朋友全栈君。
目录
JWT(JSON Web Token) 深受开发者的喜爱,主要流程如下:token,并将其返回给客户端token,将其存储在 cookie 或者 localStroge 中cookie 或者header 携带该 tokentoken 的有效性,通过才返回响应的数据
基于 Token 认证流程
Cookie 是不允许跨域访问的,这一点对 Token 机制是不存在的,前提是传输的用户认证信息通过 HTTP 头传输Token 机制在服务端不需要存储 session 信息,因为 Token 自身包含了所有登录用户的信息,只需要在客户端的 cookie 或本地介质存储状态信息http 协议的客户端,就可以使用 token 认证。cookie,所以采用 token 认证方式不会发生 CSRF,所以也就无需考虑 CSRF 的防御JWT 实际上就是一个字符串,它由三部分组成:头部、载荷与签名。中间用点 . 分隔成三个部分。注意 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 里面, 也可以储存在 localStorageJWTJWT 保存在 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);
}
}发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/170852.html原文链接:https://javaforall.cn