精华内容
下载资源
问答
  • JWT token

    2018-04-25 16:15:32
    JWT tokentoken的组成 token串的生成流程。 token在客户端与服务器端的交互流程 Token的优点和思考 参考代码:核心代码使用参考,不是全部代码JWT token的组成头部(Header),格式如下: { “typ”: “JWT”,...

    JWT token

    token的组成 
    token串的生成流程。 
    token在客户端与服务器端的交互流程 
    Token的优点和思考 
    参考代码:核心代码使用参考,不是全部代码

    JWT token的组成

    头部(Header),格式如下: 

    “typ”: “JWT”, 
    “alg”: “HS256” 

    由上可知,该token使用HS256加密算法,将头部使用Base64编码可得到如下个格式的字符串:

    eyJhbGciOiJIUzI1NiJ9

    有效载荷(Playload): 

    “iss”: “Online JWT Builder”, 
    “iat”: 1416797419, 
    “exp”: 1448333419, 
    ……. 
    “userid”:10001 

    有效载荷中存放了token的签发者(iss)、签发时间(iat)、过期时间(exp)等以及一些我们需要写进token中的信息。有效载荷也使用Base64编码得到如下格式的字符串:

    eyJ1c2VyaWQiOjB9

    签名(Signature): 
    将Header和Playload拼接生成一个字符串str=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOjB9”,使用HS256算法和我们提供的密钥(secret,服务器自己提供的一个字符串)对str进行加密生成最终的JWT,即我们需要的令牌(token),形如:str.”签名字符串”。

    token在服务与客户端的交互流程

    1:客户端通过用户名和密码登录 
    2:服务器验证用户名和密码,若通过,生成token返回给客户端。 
    3:客户端收到token后以后每次请求的时候都带上这个token,相当于一个令牌,表示我有权限访问了 
    4:服务器接收(通常在拦截器中实现)到该token,然后验证该token的合法性(为什么能验证下面说)。若该token合法,则通过请求,若token不合法或者过期,返回请求失败。

    关于Token的思考

    服务如何判断这个token是否合法? 
    由上面token的生成可知,token中的签名是由Header和有效载荷通过Base64编码生成再通过加密算法HS256和密钥最终生成签名,这个签名位于JWT的尾部,在服务器端同样对返回过来的JWT的前部分再进行一次签名生成,然后比较这次生成的签名与请求的JWT中的签名是否一致,若一致说明token合法。由于生成签名的密钥是服务器才知道的,所以别人难以伪造。

    token中能放敏感信息吗? 
    不能,因为有效载荷是经过Base64编码生成的,并不是加密。所以不能存放敏感信息。

    Token的优点

    (1)相比于session,它无需保存在服务器,不占用服务器内存开销。 
    (2)无状态、可拓展性强:比如有3台机器(A、B、C)组成服务器集群,若session存在机器A上,session只能保存在其中一台服务器,此时你便不能访问机器B、C,因为B、C上没有存放该Session,而使用token就能够验证用户请求合法性,并且我再加几台机器也没事,所以可拓展性好就是这个意思。 
    (3)由(2)知,这样做可就支持了跨域访问。

    Java实例:JWT token使用

    部分代码来自互联网,找不到原作者了。。 
    编写JWT(Java Web Token)操作类:JavaWebToken

    public class JavaWebToken {
    
        private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);
    
        //该方法使用HS256算法和Secret:bankgl生成signKey
        private static Key getKeyInstance() {
            //We will sign our JavaWebToken with our ApiKey secret
            SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
            byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("bankgl");
            Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
            return signingKey;
        }
    
        //使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
        public static String createJavaWebToken(Map<String, Object> claims) {
            return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();
        }
    
        //解析Token,同时也能验证Token,当验证失败返回null
        public static Map<String, Object> parserJavaWebToken(String jwt) {
            try {
                Map<String, Object> jwtClaims =
                        Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();
                return jwtClaims;
            } catch (Exception e) {
                log.error("json web token verify failed");
                return null;
            }
        }
    }

    编写登录Conreoller,在服务器端给客户返回token.

    public LoginStatusMessage checkUserAndPassword(
        @RequestParam(value="username",required=true) String username,
        @RequestParam(value="password",required=true) String password,User user,HttpServletRequest request) throws Exception{
            User u = new User();
            //登录成功
            if((u = userService.checkUsernameAndPassword(user)) != null){
                Map<String,Object> m = new HashMap<String,Object>();
                m.put("userid", user.getUserid());
                String token = JavaWebToken.createJavaWebToken(m);
                System.out.println(token);
                LoginStatusMessage lsm = new LoginStatusMessage();
                lsm.setUser(u);
                lsm.setToken(token);
                return lsm;
            };
            //登录失败,返回Null
            return null;
        }

    在拦截器中对请求中的Token验证(部分代码,表示下意思):

    String token = request.getParameter("token");
                if(JavaWebToken.parserJavaWebToken(token) != null){
                    //表示token合法
                    return true;
                }else{
                    //token不合法或者过期
                    return false;
                }
    展开全文
  • jwt token

    2020-05-26 09:18:41
    package com.example.demo.test.token; import java.util.Date; import java.util.HashMap; import java.util.Map; import com.alibaba.fastjson.JSON; import com.auth0.jwt.JWT; import ...

    package com.example.demo.test.token;

    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;

    import com.alibaba.fastjson.JSON;
    import com.auth0.jwt.JWT;
    import com.auth0.jwt.algorithms.Algorithm;
    import com.auth0.jwt.interfaces.DecodedJWT;
    import com.auth0.jwt.interfaces.JWTVerifier;

    public class JwtToken {

        // 过期时间
        private static final long EXPIRE_TIME = 15 * 60 * 1000; // 15min
        // 私钥
        private static final String TOKEN_SECRET = "privateKey";

    //    public static final String TOKEN_AES_KEY = "xiangli8Token";
    //    public static final String REFREH_TOKEN_AES_KEY = "xiangli8RefreshToken";
    //    public static final String JWT_TYP = "JWT";
    //    public static final String JWT_ALG = "AES";
    //    public static final String JWT_EXP = "30";
    //    public static final String JWT_ISS = "xiangli8";

        public static String createToken(String userId, String pwd) {

    //        String token= JWT.create().withAudience("audience")
    //                   .withIssuedAt(new Date())
    //                   .withSubject("subject")
    //                   .withExpiresAt(new Date()).withJWTId("jtiid")
    //                   .sign(Algorithm.HMAC256("123456"));

            try {
                long nowTime = System.currentTimeMillis();
                // 设置签发时间
                Date nowDate = new Date(nowTime);
                // 设置过期时间
                Date ExpiresDate = new Date(nowTime + EXPIRE_TIME);
                // 私钥和加密算法
                Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
                // 设置头部信息
                Map<String, Object> header = new HashMap<>(2);
                header.put("Type", "Jwt");
                header.put("alg", "HS256");
                // 返回token字符串
                return JWT.create().withHeader(header).withClaim("userId", userId).withClaim("pwd", pwd)
                        .withIssuedAt(nowDate).withExpiresAt(ExpiresDate).sign(algorithm);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }

        }

        /**
         * token解密jwt
         * 
         * @param token
         * @return
         * @throws Exception
         */
        public static DecodedJWT getJWT(String token) {
            try {
                Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
                JWTVerifier verifier = JWT.require(algorithm).build();
                DecodedJWT jwt = verifier.verify(token);
                return jwt;
            } catch (Exception e) {
            }
            return null;
        }

        /**
         * 检验token是否正确
         * 
         * @param **token**
         * @return
         */
        public static boolean verify(String token) {
            DecodedJWT jwt = getJWT(token);
    //            String userId = jwt.getClaim("userId").asString();
            if (null != jwt) {
                return true;
            }
            return false;
        }

    }
     

     

     

    测试

     

        public static void main(String[] args) {
            // TODO Auto-generated method stub

            String token = JwtToken.createToken("zhangsan", "1234qwer");

            System.out.println("token:" + token);
            token="eyJUeXBlIjoiSnd0IiwidHlwIjoiSldUIiwiYWxnIjoiSFMyNTYifQ.eyJwd2QiOiIxMjM0cXdlciIsImV4cCI6MTU5MDQ1ODA4NiwidXNlcklkIjoiemhhbmdoYW8iLCJpYXQiOjE1OTA0NTcxODZ9.cVcq-FTCqhESpIy3_vvJJzPrGy-ZEy4lGKnQxLMjsgY" + 
                    "";
            boolean result = JwtToken.verify(token);

            try {
                DecodedJWT jwt = JwtToken.getJWT(token);

                if(null!=jwt) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy‐MM‐dd hh:mm:ss");
                    System.out.println("签发时间:" + sdf.format(jwt.getIssuedAt()));
                    System.out.println("过期时 间:" + sdf.format(jwt.getExpiresAt()));
                    System.out.println("当前时间:" + sdf.format(new Date()));
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.println("token is:" + result);

        }

    展开全文
  • 前言在前后端分离的开发模式下,前端用户登录成功后后端服务会给用户颁发一个jwt token。前端(如vue)在接收到jwt token后会将token存储到LocalStorage中。后续每次请求都会将此token放在请求头中传递到后端服务,...

    204307703752a3c6eb204f3db9c5dff7.png

    前言

    在前后端分离的开发模式下,前端用户登录成功后后端服务会给用户颁发一个jwt token。前端(如vue)在接收到jwt token后会将token存储到LocalStorage中。

    后续每次请求都会将此token放在请求头中传递到后端服务,后端服务会有一个过滤器对token进行拦截校验,校验token是否过期,如果token过期则会让前端跳转到登录页面重新登录。

    因为jwt token中一般会包含用户的基本信息,为了保证token的安全性,一般会将token的过期时间设置的比较短。

    但是这样又会导致前端用户需要频繁登录(token过期),甚至有的表单比较复杂,前端用户在填写表单时需要思考较长时间,等真正提交表单时后端校验发现token过期失效了不得不跳转到登录页面。

    如果真发生了这种情况前端用户肯定是要骂人的,用户体验非常不友好。本篇内容就是在前端用户无感知的情况下实现token的自动续期,避免频繁登录、表单填写内容丢失情况的发生。

    实现原理

    jwt token自动续期的实现原理如下:

    1. 登录成功后将用户生成的 jwt token 作为key、value存储到cache缓存里面 (这时候key、value值一样),将缓存有效期设置为 token有效时间的2倍。
    2. 当该用户再次请求时,通过后端的一个 jwt Filter 校验前端token是否是有效token,如果前端token无效表明是非法请求,直接抛出异常即可;
    3. 根据规则取出cache token,判断cache token是否存在,此时主要分以下几种情况:
    • cache token 不存在
      这种情况表明该用户账户空闲超时,返回用户信息已失效,请重新登录。
    • cache token 存在,则需要使用jwt工具类验证该cache token 是否过期超时,不过期无需处理。
      过期则表示该用户一直在操作只是token失效了,后端程序会给token对应的key映射的value值重新生成jwt token并覆盖value值,该缓存生命周期重新计算。

    实现逻辑的核心原理:前端请求Header中设置的token保持不变,校验有效性以缓存中的token为准。

    代码实现(伪码)

    1. 登录成功后给用户签发token,并设置token的有效期
    ...
    SysUser sysUser = userService.getUser(username,password);
    if(null !== sysUser){
        String token = JwtUtil.sign(sysUser.getUsername(), 
    sysUser.getPassword());
    }
    ...


    public static String sign(String username, String secret) {
        //设置token有效期为30分钟
     Date date = new Date(System.currentTimeMillis() + 30 * 60 * 1000);
     //使用HS256生成token,密钥则是用户的密码
     Algorithm algorithm = Algorithm.HMAC256(secret);
     // 附带username信息
     return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm);
    }
    1. 将token存入redis,并设定过期时间,将redis的过期时间设置成token过期时间的两倍
    Sting tokenKey = "sys:user:token" + token;
    redisUtil.set(tokenKey, token);
    redisUtil.expire(tokenKey, 30 * 60 * 2);
    1. 过滤器校验token,校验token有效性
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        //从header中获取token
     String token = httpServletRequest.getHeader("token")
     if(null == token){
      throw new RuntimeException("illegal request,token is necessary!")
     }
        //解析token获取用户名
     String username = JwtUtil.getUsername(token);
     //根据用户名获取用户实体,在实际开发中从redis取
     User user = userService.findByUser(username);
        if(null == user){
      throw new RuntimeException("illegal request,token is Invalid!")
        }
     //校验token是否失效,自动续期
     if(!refreshToken(token,username,user.getPassword())){
      throw new RuntimeException("illegal request,token is expired!")
     }
     ...
    }
    1. 实现token的自动续期
    public boolean refreshToken(String token, String userName, String passWord) {
     Sting tokenKey = "sys:user:token" + token ;
     String cacheToken = String.valueOf(redisUtil.get(tokenKey));
     if (StringUtils.isNotEmpty(cacheToken)) {
      // 校验token有效性,注意需要校验的是缓存中的token
      if (!JwtUtil.verify(cacheToken, userName, passWord)) {
       String newToken = JwtUtil.sign(userName, passWord);
       // 设置超时时间
       redisUtil.set(tokenKey, newToken) ;
       redisUtil.expire(tokenKey, 30 * 60 * 2);
      }
      return true;
     }
     return false;
    }
    ...

    public static boolean verify(String token, String username, String secret) {
     try {
      // 根据密码生成JWT效验器
      Algorithm algorithm = Algorithm.HMAC256(secret);
      JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
      // 效验TOKEN
      DecodedJWT jwt = verifier.verify(token);
      return true;
     } catch (Exception exception) {
      return false;
     }
    }

    本文中jwt的相关操作是基于 com.auth0.java-jwt 实现,大家可以通过阅读原文获取 JwtUtil 工具类。

    小结

    jwt token实现逻辑的核心原理是 前端请求Header中设置的token保持不变,校验有效性以缓存中的token为准,千万不要直接校验Header中的token。实现原理部分大家好好体会一下,思路比实现更重要!

    展开全文
  • token在客户端与服务器端的交互流程Token的优点和思考参考代码:核心代码使用参考,不是全部代码JWT token的组成头部(Header),格式如下:{“typ”: “JWT”,“alg”: “HS256”}由上可知,该token使用HS256加密算法...

    本文你能学到什么?

    token的组成

    token串的生成流程。

    token在客户端与服务器端的交互流程

    Token的优点和思考

    参考代码:核心代码使用参考,不是全部代码

    JWT token的组成

    头部(Header),格式如下:

    {

    “typ”: “JWT”,

    “alg”: “HS256”

    }

    由上可知,该token使用HS256加密算法,将头部使用Base64编码可得到如下个格式的字符串:

    eyJhbGciOiJIUzI1NiJ9

    有效载荷(Playload):

    {

    “iss”: “Online JWT Builder”,

    “iat”: 1416797419,

    “exp”: 1448333419,

    …….

    “userid”:10001

    }

    有效载荷中存放了token的签发者(iss)、签发时间(iat)、过期时间(exp)等以及一些我们需要写进token中的信息。有效载荷也使用Base64编码得到如下格式的字符串:

    eyJ1c2VyaWQiOjB9

    签名(Signature):

    将Header和Playload拼接生成一个字符串str=“eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyaWQiOjB9”,使用HS256算法和我们提供的密钥(secret,服务器自己提供的一个字符串)对str进行加密生成最终的JWT,即我们需要的令牌(token),形如:str.”签名字符串”。

    token在服务与客户端的交互流程

    1:客户端通过用户名和密码登录

    2:服务器验证用户名和密码,若通过,生成token返回给客户端。

    3:客户端收到token后以后每次请求的时候都带上这个token,相当于一个令牌,表示我有权限访问了

    4:服务器接收(通常在拦截器中实现)到该token,然后验证该token的合法性(为什么能验证下面说)。若该token合法,则通过请求,若token不合法或者过期,返回请求失败。

    关于Token的思考

    服务如何判断这个token是否合法?

    由上面token的生成可知,token中的签名是由Header和有效载荷通过Base64编码生成再通过加密算法HS256和密钥最终生成签名,这个签名位于JWT的尾部,在服务器端同样对返回过来的JWT的前部分再进行一次签名生成,然后比较这次生成的签名与请求的JWT中的签名是否一致,若一致说明token合法。由于生成签名的密钥是服务器才知道的,所以别人难以伪造。

    token中能放敏感信息吗?

    不能,因为有效载荷是经过Base64编码生成的,并不是加密。所以不能存放敏感信息。

    Token的优点

    (1)相比于session,它无需保存在服务器,不占用服务器内存开销。

    (2)无状态、可拓展性强:比如有3台机器(A、B、C)组成服务器集群,若session存在机器A上,session只能保存在其中一台服务器,此时你便不能访问机器B、C,因为B、C上没有存放该Session,而使用token就能够验证用户请求合法性,并且我再加几台机器也没事,所以可拓展性好就是这个意思。

    (3)由(2)知,这样做可就支持了跨域访问。

    Java实例:JWT token使用

    部分代码来自互联网,找不到原作者了。。

    编写JWT(Java Web Token)操作类:JavaWebToken

    public classJavaWebToken {private static Logger log = LoggerFactory.getLogger(JavaWebToken.class);//该方法使用HS256算法和Secret:bankgl生成signKey

    private staticKey getKeyInstance() {//We will sign our JavaWebToken with our ApiKey secret

    SignatureAlgorithm signatureAlgorithm =SignatureAlgorithm.HS256;byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary("bankgl");

    Key signingKey= newSecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());returnsigningKey;

    }//使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷

    public static String createJavaWebToken(Mapclaims) {returnJwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, getKeyInstance()).compact();

    }//解析Token,同时也能验证Token,当验证失败返回null

    public static MapparserJavaWebToken(String jwt) {try{

    Map jwtClaims =Jwts.parser().setSigningKey(getKeyInstance()).parseClaimsJws(jwt).getBody();returnjwtClaims;

    }catch(Exception e) {

    log.error("json web token verify failed");return null;

    }

    }

    }

    编写登录Conreoller,在服务器端给客户返回token.

    publicLoginStatusMessage checkUserAndPassword(

    @RequestParam(value="username",required=true) String username,

    @RequestParam(value="password",required=true) String password,User user,HttpServletRequest request) throwsException{

    User u= newUser();//登录成功

    if((u = userService.checkUsernameAndPassword(user)) != null){

    Map m = new HashMap();

    m.put("userid", user.getUserid());

    String token=JavaWebToken.createJavaWebToken(m);

    System.out.println(token);

    LoginStatusMessage lsm= newLoginStatusMessage();

    lsm.setUser(u);

    lsm.setToken(token);returnlsm;

    };//登录失败,返回Null

    return null;

    }

    在拦截器中对请求中的Token验证(部分代码,表示下意思):

    String token = request.getParameter("token");if(JavaWebToken.parserJavaWebToken(token) != null){//表示token合法

    return true;

    }else{//token不合法或者过期

    return false;

    }

    展开全文
  • token在客户端与服务器端的交互流程Token的优点和思考参考代码:核心代码使用参考,不是全部代码JWT token的组成头部(Header),格式如下:{“typ”: “JWT”,“alg”: “HS256”}由上可知,该token使用HS256加密算法...
  • JWT Token

    2016-03-02 14:05:22
    json web token. http://jwt.io/
  • 退出登录时,如果不使JWT Token失效会产生如下2个问题问题1-未过期的token还是可以用要是用户在多个设备登录了,而且本地保存了token。当一个地方丢弃token,但是这个token要是没有过期,那之前token还是可以用的。...
  • 本文介绍jwt token在laravel中的安装使用,解决token验证的问题 一、查看laravel版本选定适合自己框架的jwt版本,不同版本之间会有意想不到的惊喜(坑) 根据自己laravel版本不同使用jwt-auth版本建议如下: ...
  • jwt token 实现

    2018-07-27 14:30:07
    本例子教你如何在你的项目中搭建jwt token授权登录,代码清晰易懂。
  • JWT Token刷新方案

    万次阅读 热门讨论 2019-01-22 20:42:30
    JWT TOKEN刷新方案 环境 Springboot,Redis 需求 由于是前后端分离的项目,需要使用JWT Token来校验用户信息,保证用户信息安全可靠,不会被重放攻击。 问题 JWT Token如不设置有效期,刷新周期,他人一旦拿到Token...
  • lcobucci.zip jwt token

    2020-05-12 08:16:05
    lcobucci.zip jwt tokenlcobucci.zip jwt tokenlcobucci.zip jwt tokenlcobucci.zip jwt tokenlcobucci.zip jwt tokenlcobucci.zip jwt token
  • 主要介绍了thinkphp框架使用JWTtoken的方法,结合实例形式分析了JWTtoken的功能、原理及thinkPHP使用JWTtoken实现签名验证的相关操作技巧,需要的朋友可以参考下
  • JWT Token生成及验证

    2020-07-16 17:07:57
    JWT Token生成及验证:JSON WEB TOKEN,简单谈谈TOKEN的使用及在C#中的实现
  • web api JWT token认证

    2020-04-24 11:20:26
    web api JWT token认证 Demo 代码,包含跨域访问 api设置。
  • jwttoken解析逻辑

    2020-08-30 20:38:10
    进行解析,只要输入jwttoken即可看到解析结果,便于编码时获取自己需要的结果。 func Getnssa(jwttoken string) (ns, sa string) { //SecretKey是自己定义的一个常量 claims, err := ParseToken(jwttoken, []...
  • 前言在前后端分离的开发模式下,前端用户登录成功后后端服务会给用户颁发一个jwt token。前端(如vue)在接收到jwt token后会将token存储到LocalStorage中。后续每次请求都会将此token放在请求头中传递到后端服务,...
  • 1. 前言Json Web Token(JWT) 近几年是前后端分离常用的Token技术,是目前最流行的跨域身份验证解决方案。你可以通过文章JWT。今天我们来手写一个通用的JWT服务。DEMO获取方式在文末,实现在jwt相关包下2. spring-...
  • 1. 前言Json Web Token (JWT) 近几年是前后端分离常用的 Token 技术,是目前最流行的跨域身份验证解决方案。你可以通过文章 一文了解web无状态会话token技术JWT 来了解 JWT。今天我们来手写一个通用的 JWT 服务。...
  • 之前一篇文章简单介绍了下JWT的用法,涉及到token的签发和验证。有人说JWT不适合用于替换传统的 session+cookies 机制用于Web应用的用户登录状态维护,很大原因就是这块问题。虽然之前的案例里面,我们可以成功在登录...
  • JWT TOKEN刷新方案一、环境Springboot,Redis二、需求最近在做用户中心,需要向其他服务签发JWT Token,使用Token来获取用户信息,保证用户信息安全可靠,不会被重放攻击。三、问题JWT Token设置有效期,一旦失效...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 15,978
精华内容 6,391
关键字:

jwttoken