1
0
wiki/Tech/computer-security/用户安全/用户鉴权/Token 鉴权.md
2023-11-09 17:30:33 +08:00

87 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Token 鉴权
description: Token 鉴权
keywords:
- Token
- 鉴权
tags:
- 计算机安全/用户安全
sidebar_position: 3
author: 7Wate
date: 2022-08-31
---
## Token 鉴权
现在我们已经得知Session-Cookie 的一些缺点,以及 Session 的维护给服务端造成很大困扰,我们必须找地方存放它,又要考虑分布式的问题,甚至要单独为了它启用一套 Redis 集群。那有没有更好的办法?
于是 Token 就应运而生了
### Token令牌
Token 是一个令牌,客户端访问服务器时,验证通过后服务端会为其签发一张令牌,之后,客户端就可以携带令牌访问服务器,服务端只需要验证令牌的有效性即可。一句话概括:**访问资源接口API时所需要的资源凭证**
#### Token 的组成
一般 Token 的组成由 **uid** (用户唯一的身份标识)+ **time**(当前时间的时间戳) + **sign** 签名Token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)
#### Token 的认证流程图
![Token 的认证流程图](https://static.7wate.com/img/2022/08/30/40b2dbfe8f84a.png)
#### Token 认证步骤解析
1. **客户端:** 输入用户名和密码请求登录校验。
2. **服务器:** 收到请求验证用户名与密码;验证成功后,服务端会签发一个 Token并把这个 Token 发送给客户端。
3. **客户端:** 收到 Token 以后需要把它存储起来Web 端一般会放在 localStorage 或 Cookie 中,移动端原生 APP 一般存储在本地缓存中。
4. **客户端:** 再次向服务端请求 API 资源的时候,将 Token 通过 HTTP 请求头 Authorization 字段或者其它方式发送给服务端。
5. **服务器:** 收到请求,然后去验证客户端请求里面带着的 Token 如果验证成功就向客户端返回请求的数据否则拒绝返还401
#### Token 的优点
- **服务端无状态化、可扩展性好:** Token 机制在服务端不需要存储会话Session信息因为 Token 自身包含了其所标识用户的相关信息,这有利于在多个服务间共享用户状态。
- **支持 APP 移动端设备。**
- **安全性好:** 有效避免 CSRF 攻击(因为不需要 Cookie
- **支持跨程序调用:** 因为 Cookie 是不允许跨域访问的,而 Token 则不存在这个问题。
#### Token 的缺点
- **配合:** 需要前后端配合处理。
- **占带宽:** 正常情况下比 sid 更大,消耗更多流量,挤占更多宽带。
- **性能问题:** 虽说验证 Token 时不用再去访问数据库或远程服务进行权限校验,但是需要对 Token 加解密等操作,所以会更耗性能。
- **有效期短:** 为了避免 Token 被盗用,一般 Token 的有效期会设置的较短,所以就有了 Refresh Token。
### Refresh Token刷新 Token
业务接口用来鉴权的 Token我们称之为 Access Token。为了安全我们的 Access Token 有效期一般设置较短,以避免被盗用。但过短的有效期会造成 Access Token 经常过期,过期后怎么办呢?
一种办法是**刷新 Access Token**,让用户重新登录获取新 Token会很麻烦。另一种办法是再来一个 Token一个专门生成 Access Token 的 Token我们称为 **Refresh Token**
- **Access Token** 用来访问业务接口,由于有效期足够短,盗用风险小,也可以使请求方式更宽松灵活;
- **Refresh Token** 用来获取 Access Token有效期可以长一些通过独立服务和严格的请求方式增加安全性由于不常验证也可以如前面的 Session 一样处理;
#### Refresh Token 的认证流程图
![Refresh Token 的认证流程图](https://static.7wate.com/img/2022/08/30/0f634bdff18ca.png)
#### Refresh Token 认证步骤解析
1. **客户端:** 输入用户名和密码请求登录校验。
2. **服务端:** 收到请求,验证用户名与密码;验证成功后,服务端会签发一个 Access Token 和 Refresh Token 并返回给客户端;
3. **客户端:** 把 Access Token 和 Refresh Token 存储在本地;
4. **客户端:** 请求数据时,携带 Access Token 传输给服务端;
5. **服务端**
- 验证 Access Token 有效:正常返回数据
- 验证 Access Token 过期:拒绝请求
6. **客户端** ( Access Token 已过期) **** 则重新传输 Refresh Token 给服务端;
7. **服务端** ( Access Token 已过期) **** 验证 Refresh Token ,验证成功后返回新的 Access Token 给客户端;
8. **客户端:** 重新携带新的 Access Token 请求接口;
### Token 和 Session-Cookie 的区别
Session-Cookie 和 Token 有很多类似的地方,但是 Token 更像是 Session-Cookie 的升级改良版。
- **存储地不同:** Session 一般是存储在服务端Token 是无状态的,一般由前端存储。
- **安全性不同:** Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击。
- **支持性不同:** Session-Cookie 认证需要靠浏览器的 Cookie 机制实现,如果遇到原生 NativeAPP 时这种机制就不起作用了,或是浏览器的 Cookie 存储功能被禁用,也是无法使用该认证机制实现鉴权的;而 Token 验证机制丰富了客户端类型。