0x01 Token
- Token=令牌。服务端生成的一串字符串。是客户端进行请求的一个标识,用来作为访问资源的凭据。
- 类似于临时的证书签名, 并且是一种服务端无状态的认证方式,非常适合于 REST API 的场景。所谓无状态就是服务端并不会保存身份认证相关的数据。
0x02 Token组成
- UID:用户唯一的身份标识
- TIME:时间戳
- Sign:签名(token的前几位以哈希算法压缩成的一定长度的十六进制字符串)
- 固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库
0x03 Token分类
- refresh token 负责身份认证
- access token 负责请求资源
第一次获取Token的流程

- 1.首先需要向 Google API 注册应用程序,注册完毕之后会拿到认证信息(credentials)包括ID 和 secret。不是所有的程序类型都有 secret。
- 2.接下来就要向 Google 请求 access token。如果想访问的是用户资源,这里就会提醒用户进行授权。
- 3.如果用户授权完毕。Google 就会返回 access token。又或者是返回授权代码(authorization code),再通过代码取得 access token (注意:第三步通过code兑换access token的过程中Google 并不会仅仅返回 access token,还会返回额外的信息,这其中和之后更新相关的就是 refresh token。一旦 access token 过期,就可以通过 refresh token 再次请求 access token。)
- 4.token 获取到之后,就能够带上 token 访问 API 了
1 Access Token
- 有效期限,过期就要重新获取,可通过refresh token重新获取
2 Refresh Token
如果 refesh token 也过期了怎么办?这就需要用户重新登陆授权了
虽然 refresh token 和 access token 都由 IdP 发出,但是 access token 还要和 SP 进行数据交换,如果公用的话这样就会有身份泄露的可能。并且 IdP 和 SP 可能是完全不同的服务提供的。而在第一小节中之所以没有这样的顾虑是因为 IdP 和 SP 都是 Google
0x04 Token Auth原理

- 1.客户端使用用户名和密码请求登录
- 2.服务端收到请求,验证用户名和密码
- 3.验证成功后,服务端会生成一个Token,然后把Token发送给客户端
- 4.客户端收到Token后把它保存起来(不需要Session一样存储到服务端),可以放在Cookie或者Local Storage(本地存储)
- 5.客户端每次想服务端发送请求的时候都需要带上服务端发给的Token
- 6.服务端收到请求,然后去验证客户端请求里面带着的Token,如果验证成功,就向客户端返回请求的数据。
0x05 Token Auth的Token选择分类
1 设备的MAC地址作为Token
客户端:客户端在登录时获取设备的MAC地址,将其作为参数传递到服务端
服务端:服务端接收到该参数后,便用一个变量来接收,同时将其作为token保存在数据库,并将该token设置到session中。客户端每次请求的时候都要统一拦截,将客户端传递的token和服务器端session中的token进行对比,相同则登录成功,不同则拒绝
优点:
- 1.统一了客户端与服务端的唯一标识,并且保证每一个设备拥有唯一的标识。
- 2.客户端无需重新登录,只要登录一次以后一直可以使用,对于超时的问题由服务端进行处理
缺点:
服务器端需要保存mac地址
2 Session ID作为Token
- 客户端:客户端携带用户名和密码登录
- 服务端:接收到用户名和密码后进行校验,正确就将本地获取的Session ID作为token返回给客户端,客户端以后只需带上请求的数据即可
- 优点:
- 方便,不需要存储数据
- 缺点:
- 当Session过期时,客户端必须重新登录才能请求数据
3 MAC和Session ID同时作为Token
- 用于保密性比较高的应用
0x06 Token Auth的特点
- token是无状态的,用户进行任何操作时,都需要带上一个token
- token比cookie先进,更能适用于跨平台,移动平台等
- token的存在形式有很多种,header/requestbody/url 都可以
- token只需要存在客户端,服务器在收到数据后,进行解析
1 优点
- 支持跨域访问:Cookie是不允许垮域访问的,这一点对Token机制是不存在的,前提是传输的用户认证信息通过HTTP头传输。
- 无状态(也称:服务端可扩展行):Token机制在服务端不需要存储session信息,因为Token 自身包含了所有登录用户的信息,只需要在客户端的cookie或本地介质存储状态信息。
- **更适用CDN: **可以通过内容分发网络请求服务端的所有资料(如:javascript,HTML,图片等),而服务端只要提供API即可。
- **去耦: **不需要绑定到一个特定的身份验证方案。Token可以在任何地方生成,只要在你的API被调用的时候,你可以进行Token生成调用即可。
- **更适用于移动应用: **当客户端是一个原生平台(iOS, Android,Windows 8等)时,Cookie是不被支持的(你需要通过Cookie容器进行处理),这时采用Token认证机制就会简单得多。
- 防止CSRF:因为不再依赖于Cookie,所以就不需要考虑对CSRF(跨站请求伪造)的防范。
- 性能: 一次网络往返时间(通过数据库查询session信息)总比做一次HMACSHA256计算 的Token验证和解析要费时得多。
- 不需要为登录页面做特殊处理: 如果使用Protractor做功能测试的时候,不再需要为登录页面做特殊处理。
- 基于标准化:API可以采用标准化的 JSON Web Token (JWT)。这个标准已经存在多个后端库(.NET, Ruby, Java,Python,PHP)和多家公司的支持(如:Firebase,Google, Microsoft)。
2 缺点
0x07 TokenAuth携带token的方式
- HTTP Header
- URL参数
- 提供的类库
0x08 Token的存储
数据库
- 查询时间长
- 易丢失,重新认证麻烦
内存
- 查询速度快
- 不需太担心内存占用,token就算32位且用户百万千万级也占用不了太多内存
0x09 Token的加密
对称加密:在存储的时候把token进行对称加密存储,用到的时候再解密
非对称加密/签名算法:签名方式(请求URL、时间戳、Token三者合并)通过签名算法签名
网络层面上Token使用明文传输的话是非常危险的,所以一定要使用HTTPS协议
0x10 Token Auth应用
1 Web认证(且防止CSRF)
2 APP认证
1.用户在登录APP时,APP端发送加密的用户名和密码到服务器
2.服务器验证用户名和密码,如果验证成功,就会生成相应位数的字符产作为token存储到服务器中,并且将该token返回给APP端。
3.以后APP再次请求时,凡是需要验证的地方都要带上该token,然后服务器端验证token。其中,服务器上会给token设置一个有效期,每次APP请求的时候都验证token和有效期。
- 成功:返回所需要的结果
- 失败:返回错误信息,让用户重新登录。