码迷,mamicode.com
首页 > Web开发 > 详细

JWT(JSON WEB TOKEN)实例

时间:2019-07-08 23:36:15      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:dig   after   cte   contains   admin   details   jwt   总结   iges   

JWT的工具类 加密解密工具

package top.wintp.crud.util;

import com.auth0.jwt.JWTSigner;
import com.auth0.jwt.JWTVerifier;
import com.fasterxml.jackson.databind.ObjectMapper;

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

/**
 * @description: description:  JWT的工具类
 * <p>
 * @author: pyfysf
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: pyfysf@163.com
 * <p>
 * @time: 2018/11/16
 */
public class JWTUtils {
    private static final String SECRET = "XX#$%()(#*!()!KLPYFYSFWINTOP WT>DFklsfajd f>?DFDSfWINTPT>Dasgdls.topwintp.stopxafkdlspyfysfW";

    private static final String EXP = "exp";

    private static final String PAYLOAD = "payload";

    //加密,传入一个对象和有效期
    public static <T> String sign(T object, long maxAge) {
        try {
            final JWTSigner signer = new JWTSigner(SECRET);
            final Map<String, Object> claims = new HashMap<String, Object>();
            ObjectMapper mapper = new ObjectMapper();
            String jsonString = mapper.writeValueAsString(object);
            claims.put(PAYLOAD, jsonString);
            claims.put(EXP, System.currentTimeMillis() + maxAge);
            return signer.sign(claims);
        } catch (Exception e) {
            return null;
        }
    }

    //解密,传入一个加密后的 token字符串和解密后的类型
    public static <T> T unsign(String jwt, Class<T> classT) {
        final JWTVerifier verifier = new JWTVerifier(SECRET);
        try {
            final Map<String, Object> claims = verifier.verify(jwt);
            if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
                long exp = (Long) claims.get(EXP);
                long currentTimeMillis = System.currentTimeMillis();
                if (exp > currentTimeMillis) {
                    String json = (String) claims.get(PAYLOAD);
                    ObjectMapper objectMapper = new ObjectMapper();
                    return objectMapper.readValue(json, classT);
                }
            }
            return null;
        } catch (Exception e) {
            return null;
        }
    }

}

登录的接口


    @RequestMapping("/login")
    @ResponseBody
    public Map<String, Object> login(User user) {
        logger.info("LoginController  login()   username   " + user.getUsername());
        logger.info("LoginController  login()   password   " + user.getPassword());
        Map<String, Object> resultMap = new HashMap<>();

        //先到数据库验证 用户名密码
        //Integer loginId = userService.checkLogin(login);
        Integer loginId = 1;
        if (null != loginId) {
            //User user = userService.getUserByLoginId(loginId);
            user.setId(loginId);
            //login.setId(loginId);
            //给用户jwt加密生成token
            String token = JWTUtils.sign(user, 100000L);
            //封装成对象返回给客户端
            resultMap.put("loginId", user.getId());
            resultMap.put("token", token);
            //responseData.putDataValue("loginId", login.getId());
            //responseData.putDataValue("token", token);
            //responseData.putDataValue("user", user);
        } else {
            //responseData = ResponseData.customerError();
        }

        return resultMap;
    }

拦截器

package top.wintp.crud.interceptors;

import com.auth0.jwt.internal.org.bouncycastle.asn1.ocsp.ResponseData;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import top.wintp.crud.entity.User;
import top.wintp.crud.util.JWTUtils;

/**
 * @description: description:  登录的拦截器
 * <p>
 * @author: pyfysf
 * <p>
 * @qq: 337081267
 * <p>
 * @CSDN: http://blog.csdn.net/pyfysf
 * <p>
 * @blog: http://wintp.top
 * <p>
 * @email: pyfysf@163.com
 * <p>
 * @time: 2018/11/19
 */
public class LoginInterceptor implements HandlerInterceptor {
    private static Logger logger = LoggerFactory.getLogger(LoginInterceptor.class);

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception arg3) throws Exception {
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView model) throws Exception {
    }

    //拦截每个请求
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setCharacterEncoding("utf-8");
        String token = request.getParameter("token");
        //token不存在
        if (null != token) {
            User login = JWTUtils.unsign(token, User.class);
            String loginId = request.getParameter("loginId");
            //解密token后的loginId与用户传来的loginId不一致,一般都是token过期
            if (null != loginId && null != login) {
                if (Integer.parseInt(loginId) == login.getId()) {
                    logger.info("LoginInterceptor  preHandle()   成功   ");

                    return true;
                } else {

                    logger.info("LoginInterceptor  preHandle()   失败   ");

                    response.sendRedirect("/login/index.do");
                    return false;
                }
            } else {

                logger.info("LoginInterceptor  preHandle()   失败   ");

                response.sendRedirect("/login/index.do");
                return false;
            }
        } else {
            logger.info("LoginInterceptor  preHandle()   失败   ");
            response.sendRedirect("/login/index.do");
            return false;
        }
    }
}

博客参考:
https://www.jianshu.com/p/576dbf44b2ae
https://www.jianshu.com/p/a12fc67c9e05
https://blog.csdn.net/change_on/article/details/71191894

JWT 生成的TOKEN 生成规则

JWT详解

JWT由三个部分组成分别是header、payload、signature用.连接,如:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiJ9.d1bf66192c1bff9038bcd212ba05dfde55c40d4e2254dd99c9c7653dd27c39ba
{
    "typ": "JWT",
    "alg": "HS256"
}

typ: 类型,alg: 加密算法

将上面的json内容Base64之后就形成了JWT的第一部分

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

payload:

{
    "id": 1,
    "username": "admin"
}

这部分为用户自定义内容(不要存放敏感信息)

将上面的json内容Base64之后就形成了JWT的第二部分

eyJpZCI6MSwidXNlcm5hbWUiOiJhZG1pbiJ9

signature:

第三部分为第一部分和第二部分的签名

let headerBase64 = new Buffer(JSON.stringify(header)).toString('base64');
let payloadBase64 = new Buffer(JSON.stringify(payload)).toString('base64');
let sha256 = crypto.createHmac('sha256', 'your salt');
sha256.update(headerBase64 + '.' + payloadBase64);
let sign = sha256.digest('hex');
let finalJwtString = headerBase64 + '.' + payloadBase64 + '.' + sign;

总结

优点

因为json的通用性,所以JWT是可以进行跨语言支持的,像JAVA,JavaScript,NodeJS,PHP等很多语言都可以使用。
因为有了payload部分,所以JWT可以在自身存储一些其他业务逻辑所必要的非敏感信息。
便于传输,jwt的构成非常简单,字节占用很小,所以它是非常便于传输的。
它不需要在服务端保存会话信息, 所以它易于应用的扩展

安全相关

1.不应该在jwt的payload部分存放敏感信息,因为该部分是客户端可解密的部分。
2.保护好secret私钥,该私钥非常重要。
3.如果可以,请使用https协议

JWT(JSON WEB TOKEN)实例

标签:dig   after   cte   contains   admin   details   jwt   总结   iges   

原文地址:https://www.cnblogs.com/upuptop/p/11154649.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!