zoukankan      html  css  js  c++  java
  • 学习笔记:JWT在spring中的时间

    转自:http://blog.csdn.net/ahmuamu/article/details/52216349(谢谢楼主分享)

    spring安全验证之jwt(json web token)实践

    系统开发来讲,安全验证永远是最重要的,从最原始的session、cookie验证方式,到符合restful风格、满足前后端分离需求、启用https请求,各方面都在不断变化中。本文以jwt(json web token)的实践为例,介绍一二。

    首先,来看一下jwt的概念,流程图如下所示:

    流程图

    用户发起登录请求,服务端创建一个加密后的jwt信息,作为token返回值,在后续请求中jwt信息作为请求头,服务端正确解密后可获取到存储的用户信息,表示验证通过;解密失败说明token无效或者已过期。

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

    eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiJqd3QiLCJpYXQiOjE0NzEyNzYyNTEsInN1YiI6IntcInVzZXJJZFwiOjEsXCJyb2xlSWRcIjoxfSIsImV4cCI6MTQ3MTMxOTQ1MX0.vW-pPSl5bU4dmORMa7UzPjBR0F6sqg3n3hQuKY8j35o
    

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

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

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

    {
        "sub": "1234567890",
        "name": "John Doe",
        "admin": true
    }
    

    Signature则为对Header、Payload的签名。

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

    在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)请求,来实现刷新。关于sse在前面博文中有介绍过,此处略过不提。

    本文完整源代码存放于github,地址:https://github.com/ahmu/spring-authorization-demo

    参考资料:

    1.jwt官方网站:https://jwt.io/

    2.jjwt项目:https://github.com/jwtk/jjwt

    3.Introduction to JSON Web Tokens:https://jwt.io/introduction/

    4.How to Create and verify JWTs in Java: https://stormpath.com/blog/jwt-java-create-verify

  • 相关阅读:
    Linux 简介
    5设计模式之桥接模式(结构模式)
    2设计模式之简单工厂模式(构造模式)
    3异步和多线程
    1设计模式之单例模式
    性能测试知多少---吞吐量
    NumberFormat DecimalFormat
    Java 005 枚举
    log4j
    Java Basic
  • 原文地址:https://www.cnblogs.com/FightingMan/p/6197624.html
Copyright © 2011-2022 走看看