APP 的 token 认证
最后更新于:2022-04-02 03:08:47
[TOC]
> [参考](https://www.jianshu.com/p/ad410836587a)
## Token&AppKey(APP)
与开放平台认证不同的是 把 AccessKey改为token
## 简要概述
1. 调用接口前,先获取一个全局唯一的令牌(Token)
2. 调用接口时,将 Token 放到 Header 头中
3. 解析 Header 头,验证是否为有效 Token,无效直接返回失败
4. 完成业务逻辑后,将业务结果与 Token 进行关联存储,设置失效时间
5. 重试时不要重新获取 Token,用要上次的 Token
### Token身份验证
1. 用户登录向服务器提供认证信息(如账号和密码),服务器验证成功后**返回Token**给客户端;
2. 客户端将Token保存在本地,后续发起请求时,**携带此Token**;
3. 服务器检查Token的有效性,有效则放行,无效(Token错误或过期)则拒绝。
> **安全隐患**:Token被劫持,伪造请求和篡改参数。
### Token+AppKey签名验证 (防篡改)
为客户端分配AppKey(密钥,用于接口加密,不参与传输),将AppKey和所有请求参数组合成源串,根据签名算法生成签名值,发送请求时将签名值一起发送给服务器验证。
### 重放攻击(可选,推荐)
timestamp+nonce方案
timestamp:生成当前时间戳
nonce:生成唯一标识符
服务器判断在timestamp的 15分钟内,是否存在nonce,存在则拒绝,不存在则通过,并记录 nonce(可以使用redis的expire,新增nonce的同时设置它的超时失效时间为15分钟
### 实现
登陆和登出请求
![97554574-5BB1-48FC-9BAD-4325DF1095B7.png](http://yanxuan.nosdn.127.net/c73227505f3e7c01dffebbd1a58fd59c.png)
#### 获取token认证
1. 发送认证信息(如账户密码)
2. 服务端接受认证信息,通过则生成 token,添加 uid 与有效期后存入数据库
2. 客户单接受服务端返回的 token, 并在后续请求中携带
#### 客户端
1. 生成当前时间戳`timestamp=now`和唯一随机字符串`nonce=random`
2. 按照请求参数名的字母**升序排列非空**请求参数(包含token)
`stringA="token=token&home=world&name=hello&work=java×tamp=now&nonce=random";`
3. 拼接密钥SecretKey
`stringSignTemp="stringA&token=token";`
4. MD5并转换为大写
`sign=MD5(stringSignTemp).toUpperCase();`
5. 最终请求
`http://api.test.com/test?name=hello&home=world&work=java×tamp=now&nonce=nonce&sign=sign;`
### 服务端
![60621CA6-77C7-4E8A-890F-BB0B3C7AAA42.png](http://yanxuan.nosdn.127.net/a45b123832049d24a8380e6c8ab7f614.png)
';