JWT鉴权
跨域认证
物联网服务离不开身份认证,常规的方法是:
- 用户发送账号密码
- 服务器验证通过后,在当前session中保存登录记录,包括用户信息、登录时间等
- 服务器向用户返回一个
session_id
,写入用户的cookie
- 之后用户每次访问都带上该cookie,服务器根据cookie携带的session_id进行身份识别
该方法需要服务器保存用户登录信息,如果服务器需要集群,或者是跨域,就必须将session共享。当然,可以考虑将session数据持久化,让服务向持久层请求数据。
但是这样的方法会给服务器或持久层带来压力,当用户量很大的时候,需要存储的数据会很大,给内存带来压力。
另一种解决方案是使用token
,由客户端保存服务器分发的token
,在请求服务时携带token
,由服务端使用对应的算法验证该token
是否合法,如果通过则继续提供服务。
JWT
就属于使用token方案的一个代表技术。
JWT概述
JWT(JSON Web Token)的原理是:服务器通过第一次认证后,生成一个JSON对象作为token返回给用户,以后的每次请求都携带该JSON对象用于鉴权,而服务器无需再保存session数据,完全靠该JSON对象验证身份。
由于是由用户存储该JSON对象,为了防止篡改,服务器在其后面会加上签名。
JWT结构
JWT由三部分组成,彼此之间使用.
分隔,并且无换行:
- Header:头部
- Payload:负载
- Signature:签名
Header描述JWT的 元数据
,包括签名算法
和token的类型
:
1 | { |
然后使用Base64进行编码
Payload存放实际需要传递的数据,有如下几个官方字段供选用:
- iss (issuer):签发人
- exp (expiration time):过期时间
- sub (subject):主题
- aud (audience):受众
- nbf (Not Before):生效时间
- iat (Issued At):签发时间
- jti (JWT ID):编号
当然也可以定义私有字段,但是注意JWT默认不加密,请不要放秘密信息在这里。
1 | { |
然后同样使用Base64进行编码
Signature是对前两个部分的签名,以防止数据篡改:
1 | HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret) |
三个部分都计算完成后,将其拼接成一个完整的字符串,中间由.
连接,然后就可以返回给用户。
JWT的使用
服务端生成JWT数据后,用户每次请求就都需要携带该JSON数据。
例如可以将其放在cookie中自动发送,但是这样不能进行跨域,因此更一般的做法是将其作为http请求的Authorization
字段进行发送
JWT的特点
- JWT默认不加密,在未加密的情况下,不要将秘密放在JWT中
- JWT可以在生成初始token后再使用密钥进行一次加密
- JWT无法中途销毁,在其有效时间之前一直保持有效
- JWT包含验证信息,要避免泄露,否则他人可以直接获得其所有权限,所以应该使用https进行传输
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 WAHAHA's blog!
评论