【Java web】JWTtoken登录校验

JWT (Json Web Token) 是为了网络应用环境间传递声明而执行的一种基于JSON的开放标准。

JWT可以校验用户的身份,传递用户的身份信息,一般用在用户登录上。

session用户认证的一般流程

  1. 用户输入账号密码, 向服务器发送请求
  2. 服务器验证账号密码是否正确, 如果正确则在该用户的session回话里保存相关的信息如id, 登录时间等
  3. 服务器向用户返回一个Cookie, 存着sessionId
  4. 用户再次请求服务器时带上sessionId.服务器根据sessionId从服务器保存的session中获取的信息.

这种方式在单服务器场景下没有太大问题
但在服务器集群下扩展性较差, session存在于不同的服务器, 则用户下次请求又必须分配到上次请求的服务器, 影响了负载均衡的能力.

CSRF: 跨站请求伪造, 如果截获了用户Cookie中的sessionId, 则很容易会受到跨站请求伪造的攻击

使用JWTToken则不会遇到该问题, 因为使用JWTToken服务器就不保存信息了, 而是token里保存着编码的信息, 并对附带一个加密的签名, 服务器接收到token可直接解密进行认证.

JWTToken认证的流程

  1. 用户输入账号密码, 向服务器发送请求.
  2. 服务器验证账号密码,返回一个加密的保存有用户信息的token
  3. 用户再次请求时带上token
  4. 服务器解析token, 取出token中的信息进行认证

JWT token的组成

三个部分

  • Header 头部
  • Payload 负载
  • Signature 签名

头部(header)

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

alg : 加密类型
typ : JWT token的类型

alg算法介绍
HS256HMAC256HMAC with SHA-256
HS384HMAC384HMAC with SHA-384
HS512HMAC512HMAC with SHA-512
RS256RSA256RSASSA-PKCS1-v1_5 with SHA-256
RS384RSA384RSASSA-PKCS1-v1_5 with SHA-384
RS512RSA512RSASSA-PKCS1-v1_5 with SHA-512
ES256ECDSA256ECDSA with curve P-256 and SHA-256
ES384ECDSA384ECDSA with curve P-384 and SHA-384
ES512ECDSA512ECDSA with curve P-521 and SHA-512

payload 负载

负载主要是存放有效信息的地方

标准中注册的声明

建议但不强制使用

iss : jwt签发者
sub : jwt所面向的用户
aud : 接收jwt的一方
exp : jwt的过期时间, 要大于签发时间
nbf : 定义一个时间前, token都是不可用的
iat : jwt的签发时间
jti : jwt的唯一身份标识, 作为一次性token, 避免重放攻击 

自定义数据

可以加入一些自己定义的数据, 用来进行用户认证

不建议存放敏感信息, 因为这部分内容不会进行加密, 而是采用base64进行编码.

id : 22
name : zhangs

signature签名

签名为jwt的第三个部分
jwt的签名是根据headers头部和payload负载通过头部中声明的加密方式进行加盐secret组合加密
secret存在服务器中, 服务器通过这个签名验证token的合法性, 防止伪造的token.

三个部分组合形成token

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload)+ "." +
  your-256-bit-secret
) 

样例

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MjIsImV4cCI6MTU1NzU4Mjc1NSwiaWF0IjoxNTU2OTc3OTU1fQ.icWwR1ysVb4p30XywCck6Fkzn6Oep45zG50NmRLc3BE

解析出来的headers

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

解析出来的payload

{
  "id": 22,
  "exp": 1557582755,
  "iat": 1556977955
}

java中使用JWTToken

导入依赖

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

创建token

	Map<String, Object> map = new HashMap<String, Object>();
 	map.put("alg", "HS256");
	map.put("typ", "JWT");
	String token = JWT.create()
                .withHeader(map)    // 添加头部
                .withClaim("id", id)   // 添加自定义数据
                .withExpiresAt(experiesDate) // 设置过期的日期
                .withIssuedAt(iatDate) // 签发时间
                .sign(Algorithm.HMAC256(SECRET)); // 加密

校验token

		JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
        DecodedJWT jwt = null;
        try {
            jwt = verifier.verify(token);
        } catch (Exception e) {
            throw new Exception("登录过期");
        }
        return jwt.getClaims();

在做登录的intercepter中加入验证逻辑

  String token = request.getHeader("token");                               // 获取请求头里的token
  if (token == null) {                                              
                // 跳转返回未登录
                request.getRequestDispatcher("/user/need_login.do").forward(request, response);
                logger.info("未登录");
            } else {
                try {
                    Map<String, Claim> map = JWTUtil.verifyToken(token);    // 该方法验证失败会抛出异常
                    int id = map.get("id").asInt();                         // 没有id也会抛出异常
                    request.setAttribute("id", id);                         // 传递参数id
                    return true;                                            // 验证成功放行
                } catch (Exception e) {                                     // 抛出异常进行跳转
                    request.getRequestDispatcher("/user/need_login.do").forward(request, response);
                    logger.info("登录过期");
                }
            }
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值