APP下载
报价宝  ›  科技  › 

系统安全-JWT(JSON Web Tokens)

报价宝 来源:baojiabao.com 发布时间:2019-11-13 15:53:00 10月02日更新
报价宝综合消息系统安全-JWT(JSON Web Tokens)

原文:https://www.jianshu.com/p/47b2d2f92add

作者:高广超

系统开发来讲,安全验证永远是最重要的,从最原始的session、cookie验证方式,到符合restful风格、满足前后端分离需求、启用https请求,各方面都在不断变化中。

概念

JWT是一种用于双方之间传递安全资讯的简洁的、URL安全的表述性宣告规范。JWT作为一个开放的标准( RFC 7519 ),定义了一种简洁的,自包含的方法用于通讯双方之间以Json物件的形式安全的传递资讯。因为数字签名的存在,这些资讯是可信的,JWT可以使用HMAC算法或者是RSA的公私秘钥对进行签名。

简洁(Compact): 可以通过URL,POST引数或者在HTTP header传送,因为资料量小,传输速度也很快自包含(Self-contained):负载中包含了所有使用者所需要的资讯,避免了多次查询数据库JWT的主要应用场景

身份认证

在这种场景下,一旦使用者完成了登陆,在接下来的每个请求中包含JWT,可以用来验证使用者身份以及对路由,服务和资源的访问许可权进行验证。由于它的开销非常小,可以轻松的在不同域名的系统中传递,所有目前在单点登入(SSO)中比较广泛的使用了该技术。

资讯交换

在通讯的双方之间使用JWT对资料进行编码是一种非常安全的方式,由于它的资讯是经过签名的,可以确保传送者传送的资讯是没有经过伪造的。

JWT的结构

加密后jwt资讯如下所示,是由.分割的三部分组成,分别为Header、Payload、Signature。

其结构看起来是这样的

xxxxx.yyyyy.zzzzz

Header

Header包含两部分资讯,alg指加密型别,可选值为HS256、RSA等等,typ=JWT为固定值,表示token的型别。

{

"alg": "HS256",

"typ": "JWT"

}

Payload

Payload是指签名信息以及内容,一般包括iss (发行者), exp (过期时间), sub(使用者资讯), aud (接收者),以及其他资讯,详细介绍请参考官网。

{

"sub": "1234567890",

"name": "John Doe",

"admin": true

}

Signature

Signature则为对Header、Payload的签名。

HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

如何使用JWT?

在身份鉴定的实现中,传统方法是在服务端储存一个session,给客户端返回一个cookie,而使用JWT之后,当用户使用它的认证资讯登陆系统之后,会返回给使用者一个JWT,使用者只需要本地储存该token(通常使用local storage,也可以使用cookie)即可。

当用户希望访问一个受保护的路由或者资源的时候,通常应该在 Authorization 头部使用 Bearer 模式新增JWT,其内容看起来是下面这样:

Authorization: Bearer

因为使用者的状态在服务端的内存中是不储存的,所以这是一种 无状态 的认证机制。服务端的保护路由将会检查请求头 Authorization 中的JWT资讯,如果合法,则允许使用者的行为。由于JWT是自包含的,因此减少了需要查询数据库的需要。

JWT的这些特性使得我们可以完全依赖其无状态的特性提供资料API服务,甚至是建立一个下载流服务。因为JWT并不使用Cookie的,所以你可以使用任何域名提供你的API服务而不需要担心跨域资源共享问题(CORS)。

在jwt官网,可以看到有不同语言的实现版本,这里使用的是java版的jjwt。话不多说,直接看程式码,加解密都很简单:

/**

* 建立 jwt

* @param id

* @param subject

* @param ttlMillis

* @return

* @throws Exception

*/

public String createJWT(String id, String subject, long ttlMillis) throws Exception {

SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256 ;

long nowMillis = System. currentTimeMillis();

Date now = new Date( nowMillis);

SecretKey key = generalKey();

JwtBuilder builder = Jwts. builder()

.setId(id)

.setIssuedAt(now)

.setSubject(subject)

.signWith(signatureAlgorithm, key);

if (ttlMillis >= 0){

long expMillis = nowMillis + ttlMillis;

Date exp = new Date( expMillis);

builder.setExpiration( exp);

}

return builder.compact();

}

/**

* 解密 jwt

* @param jwt

* @return

* @throws Exception

*/

public Claims parseJWT(String jwt) throws Exception{

SecretKey key = generalKey();

Claims claims = Jwts. parser()

.setSigningKey( key)

.parseClaimsJws( jwt).getBody();

return claims;

}

加解密的key是通过固定字串转换而生成的;subject为使用者资讯的json字串;ttlMillis是指token的有效期,时间较短,需要定时更新。

这里要介绍的token重新整理方式,是在生成token的同时生成一个有效期较长的refreshToken,后续由客户端定时根据refreshToken来获取最新的token。浏览器与服务端之间建立sse(server send event)请求,来实现重新整理。

文章标签: 报价宝 降噪耳机价格 耳机价格 红米手机价格 华为手机价格 小米手机价格 电视机价格 笔记本电脑价格 笔记本价格 汽车价格 报价宝 手机价格 笔记本价格 电视机价格 耳机价格