Token 认证流程

  • 作为目前最流行的跨域认证解决方案,JWT(JSON Web Token) 深受开发者的喜爱,主要流程如下:
  • 客户端发送账号和密码请求登录
  • 服务端收到请求,验证账号密码是否通过
  • 验证成功后,服务端会生成唯一的 token,并将其返回给客户端
  • 客户端接受到 token,将其存储在 cookie 或者 localStroge
  • 之后每一次客户端向服务端发送请求,都会通过 cookie 或者header 携带该 token
  • 服务端验证 token 的有效性,通过才返回响应的数据

基于 Token 认证流程

Token 认证优点

  • 支持跨域访问:Cookie 是不允许跨域访问的,这一点对 Token 机制是不存在的,前提是传输的用户认证信息通过 HTTP 头传输
  • 无状态: Token 机制在服务端不需要存储 session 信息,因为 Token 自身包含了所有登录用户的信息,只需要在客户端的 cookie 或本地介质存储状态信息
  • 适用性更广: 只要是支持 http 协议的客户端,就可以使用 token 认证。
  • 无需考虑CSRF: 由于不再依赖 cookie,所以采用 token 认证方式不会发生 CSRF,所以也就无需考虑 CSRF 的防御

JWT 结构

  • 一个 JWT 实际上就是一个字符串,它由三部分组成:头部载荷签名。中间用点 . 分隔成三个部分。注意 JWT 内部是没有换行的。

JWT 结构
  • 头部 / header
  • header 由两部分组成: token 的类型 JWT 和算法名称:HMACSHA256RSA
{
"alg": "HS256",
"typ": "JWT"
}
  • 载荷 / Payload
  • Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 指定七个默认字段供选择。
  • 除了默认字段之外,你完全可以添加自己想要的任何字段,一般用户登录成功后,就将用户信息存放在这里
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT
{
"iss": "xxxxxxx",
"sub": "xxxxxxx",
"aud": "xxxxxxx",
"user": [
'username': '极客飞兔',
'gender': 1,
'nickname': '飞兔小哥'
]
}
  • 签名 / Signature
  • 签名部分是对上面的 头部、载荷 两部分数据进行的数据签名
  • 为了保证数据不被篡改,则需要指定一个密钥,而这个密钥一般只有你知道,并且存放在服务端
  • 生成签名的代码一般如下:
// 其中secret 是密钥
String signature = HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

JWT 基本使用

  • 客户端收到服务器返回的 JWT,可以储存在 Cookie 里面, 也可以储存在 localStorage
  • 然后 客户端每次与服务器通信,都要带上这个 JWT
  • JWT 保存在 Cookie 里面发送请求,这样不能跨域
  • 更好的做法是放在 HTTP 请求的头信息 Authorization 字段里面
fetch('license/login', {
headers: {
'Authorization': 'X-TOKEN' + token
}
})

实战:使用 JWT 登录认证

  • 这里使用 ThinkPHP6 整合 JWT 登录认证进行实战模拟

  • 安装 JWT 扩展

composer require firebase/php-jwt
  • 封装生成 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;
}
}
  • 用户登录后,生成 JWT 标识
<?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);
}
}

实战模拟│JWT 登录认证的更多相关文章

  1. 实战模拟│单点登录 SSO 的实现

    目录 什么是单点登录 单点登录的凭证 父域 Cookie 方式 用户认证中心方式 localstorage方式 什么是单点登录 单点登录: SSO(Single Sign On) 用户只需登录一次,就 ...

  2. 【项目实践】一文带你搞定Session和JWT的登录认证方式

    以项目驱动学习,以实践检验真知 前言 登录认证,估计是所有系统中最常见的功能了,并且也是最基础.最重要的功能.为了做好这一块而诞生了许多安全框架,比如最常见的Shiro.Spring Security ...

  3. OAuth2.0实战!使用JWT令牌认证!

    大家好,我是不才陈某~ 这是<Spring Security 进阶>的第3篇文章,往期文章如下: 实战!Spring Boot Security+JWT前后端分离架构登录认证! 妹子始终没 ...

  4. 基于jwt的用户登录认证

    最近在app的开发过程中,做了一个基于token的用户登录认证,使用vue+node+mongoDB进行的开发,前来总结一下. token认证流程: 1:用户输入用户名和密码,进行登录操作,发送登录信 ...

  5. Luffy之登录认证以及JWT

    1.用户认证 在前面我们已经完成了,前端登录页面的搭建,以及路由分配,现在我们作关于登录认证部分的东西 Django提供了认证系统.认证系统包含: 用户 权限:二元(是/否)标志指示一个用户是否可以做 ...

  6. 基于JWT的Token登录认证(一)

    1.JWT简介 JSON Web Token(缩写 JWT),是目前最流行的跨域认证解决方案. session登录认证方案:用户从客户端传递用户名.密码等信息,服务端认证后将信息存储在session中 ...

  7. JWT实现登录认证实例

    JWT全称JSON Web Token,是一个紧凑的,自包含的,安全的信息交换协议.JWT有很多方面的应用,例如权限认证,信息交换等.本文将简单介绍JWT登录权限认证的一个实例操作. JWT组成 JW ...

  8. 厉害!我带的实习生仅用四步就整合好SpringSecurity+JWT实现登录认证!

    小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么锅都想甩给他,啊,不,一不小心怎么把心里话全说出来了呢?重来! 小二是新来的实习生,作为技术 leader,我还是很负责任的,有什么 ...

  9. 10分钟简单学习net core集成jwt权限认证,快速接入项目落地使用

    什么是JWT JSON Web Token(JWT)是目前最流行的跨域身份验证.分布式登录.单点登录等解决方案. JWT的官网地址:https://jwt.io/ 通俗地来讲,JWT是能代表用户身份的 ...

随机推荐

  1. WIN10 使用POWERSHELL 设置单应用KIOSK模式(win10家庭版或企业版)

    win10 使用PowerShell 设置单应用kiosk模式 win10 家版或企业版PowerShellshell 启动器 v1Autologon.exe 注意事项 win10 家庭版或企业版. ...

  2. Java安全之SnakeYaml反序列化分析

    Java安全之SnakeYaml反序列化分析 目录 Java安全之SnakeYaml反序列化分析 写在前面 SnakeYaml简介 SnakeYaml序列化与反序列化 常用方法 序列化 反序列化 Sn ...

  3. CSS书写及命名规范

    1.样式书写顺序 positioning定位::position.display.float.top. right.bottom.left.overflow.clear.z-index: box mo ...

  4. vue - Vue脚手架(终结篇)/ vue动画

    几天的内容不是很多,因为我们脚手架的学习告一段落了,也是为了跟明天开始的内容有一个区分. 明天将会有一个非常重要的内容来了,各位,vue中的ajax他来了,这个绝对是重量级,有点兴奋! 十一.TODO ...

  5. MongoDB是什么?非关系型数据库的优点?安装使用教程

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,由于球姐都有孩子了, ...

  6. Linux Troubleshooting 超实用系列 - Disk Analysis

    笔者历史文章: https://github.com/CarlJi/words 关于磁盘的使用,实际生产中以下问题会较为常见: No space left on device - 空间不足 Disk ...

  7. Java synchronized那点事

    前言 请看上篇:Java 对象头那点事 文章中的源码都有不同程度缩减,来源于openjdk8的开源代码(tag:jdk8-b120). 锁粗化过程 偏向锁 ①:markword中保存的线程ID是自己且 ...

  8. 好客租房14-在jsx中使用javascript表达式的注意点

    注意点 单大括号中可以使用任意的表达式 jsx自身也是js表达式 注意:js中的对是一个例外 写在style样式中 //导入react     import React from "reac ...

  9. 使用 gitbook 制作自己的 html 文档

    使用 gitbook 制作自己的 html 文档 步骤如下 npm install gitbook-cli -g // 全局安装 gitbook-cli <span style="te ...

  10. ethtools-网卡适配器管理

    查看网卡适配器配置信息,并且我们可以通过它修改网卡适配器的双工模式. 1.安装Ethtools [root@localhost ~]# yum -y install ethtools 2.命令语法 语 ...