JWT生成Token做登录校验

/ java / 没有评论 / 413浏览

JWT介绍

JWT(json web token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。

JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源。

JWT的构成

一个JWT实际上就是一个字符串,它由三部分组成,头部、载荷与签名。

头部(header)

JWT还需要一个头部,头部用于描述关于该JWT的最基本的信息,例如其类型以及签名所用的算法等。这也可以被表示成一个JSON对象。

{
  "typ": "JWT",
  "alg": "HS256"
}

在这里,我们说明了这是一个JWT,并且我们所用的签名算法(后面会提到)是HS256算法。

对它也要进行Base64编码,之后的字符串就成了JWT的Header(头部)。

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

载荷(Payload)

我们先将上面的添加好友的操作描述成一个JSON对象。其中添加了一些其他的信息,帮助今后收到这个JWT的服务器理解这个JWT。

信息包含三个部分

标准中注册的声明 (建议但不强制使用) :

公共的声明 :

公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明 :

私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

{
    "iss": "WingSky",
    "iat": 1441593502,
    "exp": 1441594722,
    "aud": "www.aud.com",
    "sub": "www.sub.com",
    "from_user": "B",
    "target_user": "A"
}

签名(signature)

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

这个部分需要base64加密后的header和base64加密后的payload使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分:

49UF72vSkj-sA4aHHiYN5eoZ9Nb4w5Vb45PsLF7x_NY

密钥secret是保存在服务端的,服务端会根据这个密钥进行生成token和验证,所以需要保护好。

java方式实现

Maven

<dependency>
  <groupId>com.auth0</groupId>
  <artifactId>java-jwt</artifactId>
  <version>3.1.0</version>
</dependency>

创建Token:

public static String createToken(String userId, List<PrgRole> prgRoleList) throws Exception {

		Date iatDate = new Date();

		Calendar nowTime = Calendar.getInstance();
		nowTime.add(Calendar.MINUTE, 2);
		Date expiresDate = nowTime.getTime();

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("alg", "HS256");
		map.put("typ", "JWT");
		
		Builder token = JWT.create();
		token.withHeader(map);//header
		token.withSubject(userId);//面向的对象	
		token.withClaim("userA", "A");//私有信息
		token.withExpiresAt(expiresDate);//过期时间
		token.withIssuedAt(iatDate);//签发时间
		return token.sign(Algorithm.HMAC256(SECRET));//signature	
	}

解析token


public static DecodedJWT verifyToken(String token) throws Exception {
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
		DecodedJWT jwt = null;

		try{
			jwt = verifier.verify(token);
		} catch (Exception e){
			throw new RuntimeException("Token过期");
		}

		return jwt;
	}

测试代码

public static void main(String[] args) {
		String token = createToken("userid");
		DecodedJWT jwt = JwtToken.verifyToken(token);
		String userId = jwt.getSubject();
		System.out.printf(userId);
		Map<String, Claim> claims = jwt.getClaims();
		System.out.printf(claims.get("userA").asString());
	}