JWT
JWT , 全写JSON Web Token, 是开放的行业标准RFC7591,用来实现端到端安全验证.
简单来说, 就是通过一些算法对加密字符串和JSON对象之间进行加解密。
JWT加密JSON,保存在客户端,不需要在服务端保存会话信息。,可以应用在前后端分离的用户验证上,后端对前端输入的用户信息进行加密产生一个令牌字符串, 前端再次请求时附加此字符串,后端再使用算法解密。
- 下列场景中使用JSON Web Token是很有用的:
Authorization (授权) : 这是使用JWT的最常见场景。一旦用户登录,后续每个请求都将包含JWT,允许用户访问该令牌允许的路由、服务和资源。单点登录是现在广泛使用的JWT的一个特性,因为它的开销很小,并且可以轻松地跨域使用。
Information Exchange (信息交换) : 对于安全的在各方之间传输信息而言,JSON Web Tokens无疑是一种很好的方式。因为JWTs可以被签名,例如,用公钥/私钥对,你可以确定发送人就是它们所说的那个人。另外,由于签名是使用头和有效负载计算的,您还可以验证内容没有被篡改。 - JWT只是一个标准
可以通过不过的开发语言实现,包括Java,.NET, Python,Node Js, JavaScript,Perl, Ruby,Go等。
同一种语言,不同的开发者提供了多种实现库,以Java语言为例有java-jwt、?jose4j、nimbus-jose-jwt、jjwt - https://jwt.io/ 这个网站提供了在线的基于不同算法的字符串和JSON对象的转换工具,同时也收集了不同语言的多种实现库。
- JWT的构成
Header头部: Token类型和加密算法。加密算法常见的有MD5、SHA、HMAC( Hash Message Authentication Code)。
PayLoad负载: 存放有效信息,包括
标准的声明,类似开发语言总的关键字。包括
iss(Issuser) - 签发者
sub Subject 面向主体
aud Audience 接收方
exp Expiration time 过期时间戳
nbf Not Before, 开始生效时间戳
iat(Issued at) 签发时间
jti(JWT ID): 唯一标识
公共的声明: 一般添加业务相关的必要信息,因为可解密,不建议敏感信息。
私有的声明:提供者和消费者共同定义的声明,Base64对称解密,不建议敏感信息
Signature签证
签证信息包括三部分:
Base64加密的header
Base64加密的payload
secret-密钥
使用header中声明的加密算法对Header和payload的加密连接字符串进行加盐secret组合加密。
密钥保存在服务端,服务端根据密钥进行解密验证。
java-jwt 的使用
(1) java-jwt是Java语言中推荐的JWT实现库,使用Maven导入如下:
1 2 3 4 5 | <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.8.3</version> </dependency> |
(2) 生成 token:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /** * 生成 token * */ public static String signToken(String app_key ,String app_secret){ try { //过期时间 Date date = new Date(System.currentTimeMillis()+EXPIER_TIME); // 私钥加密 Algorithm algorithm = Algorithm.HMAC256(app_secret); Map<String,Object> header = new HashMap<String, Object>(2); header.put("typ","JWT"); header.put("alg","HS256"); String token = JWT.create() .withHeader(header) .withClaim("appId",app_key) .withExpiresAt(date) .sign(algorithm); return token; }catch (Exception e){ return null; } } |
(3) 检验token是否正确:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * 检验token是否正确 * */ public static boolean verifyToken(String token,String app_id,String app_secret){ try{ Algorithm algorithm = Algorithm.HMAC256(app_secret); JWTVerifier verifier = JWT.require(algorithm).build(); DecodedJWT jwt = verifier.verify(token); String appid = jwt.getClaim("appId").asString(); if (app_id.equals(appid)){ return true; }else { return false; } }catch (Exception e){ return false; } } |