jwt工具类,使用jwt实现token认证,仅仅是生成token和校验token的有效性

导读:本篇文章讲解 jwt工具类,使用jwt实现token认证,仅仅是生成token和校验token的有效性,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

maven

<!--jwt-->
<dependency>
	<groupId>io.jsonwebtoken</groupId>
	<artifactId>jjwt</artifactId>
	<version>0.7.0</version>
</dependency>

登录的时候,把用户名和密码加密,然后生成token,放到session中
登出的时候把session中的token设置为null即可

Java代码

package util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * Jwt工具类
 *
 * @author 
 * @version 1.0
 * @date 2021/8/9 10:58
 * @since JDK 1.8
 */
public class JwtUtil {
    private static Logger logger = LoggerFactory.getLogger(JwtUtil.class);
    /**
     * token超时时间2小时,单位毫秒 7200000
     */
    public static final long EXPIRATION = 1000*60*60*2;

    /**
     * 签名key、生成token的秘钥
     */
    public static final String SIGNING_KEY = "你的密钥,长度最好为32";
    /**
     * sessiontoken 前缀
     */
    public static final String SESSION_TOKEN = "session_token";
    /**
     * Authorization 前缀
     */
    public static final String BEARER = "Bearer ";


    public static void main(String[] args) {
        String token = createToken("用户名", "密码");
        System.out.println(token);
//        String a = "加密后的字符串";
//        Claims claims = parseToken(a);
//        if (claims == null) {
//            System.out.println("token过期");
//        }
//        String s = JSONObject.toJSONString(claims);
//        String issuer = claims.getIssuer();
//        System.out.println("issuer="+issuer);
//        System.out.println(s);
//        JSONObject jsonObject = JSONObject.parseObject(s);
//        Object aud = jsonObject.get("aud");
//        System.out.println(aud);
    }

    /**
     * 解析token
     *
     * @param jsonWebToken jsonWebToken
     * @return Claims asdfa
     */
    public static Claims parseToken(String jsonWebToken, HttpServletRequest request, HttpServletResponse response) {
        Claims claims = null;
        try {
            claims = Jwts.parser()
                    .setSigningKey(SIGNING_KEY)
                    .parseClaimsJws(jsonWebToken).getBody();
            // 刷新令牌
            // token签发时间
            long issuedAt = claims.getIssuedAt().getTime();
            // 当前时间
            long currentTimeMillis = System.currentTimeMillis();
            // token过期时间
            long expirationTime = claims.getExpiration().getTime();
//            logger.info("旧的"+String.valueOf(expirationTime));
            // 1. 签发时间 < 当前时间 < (签发时间+((token过期时间-token签发时间)/2)) 不刷新token
            // 2. (签发时间+((token过期时间-token签发时间)/2)) < 当前时间 < token过期时间 刷新token并返回给前端
            // 3. tokne过期时间 < 当前时间 跳转登录,重新登录获取token
            // 验证token时间有效性【更新token的时间为:失效时间的一半,更新token】
            if ((issuedAt + ((expirationTime - issuedAt) / 2)) < currentTimeMillis && currentTimeMillis < expirationTime) {
                // 重新生成token start
                String token = createToken(claims.getIssuer(), claims.getAudience());
                // 更新token
                request.getSession().setAttribute(JwtUtil.SESSION_TOKEN, token);
            }
            return claims;
//        } catch (ExpiredJwtException e) {
//            logger.error("Token已过期: {} " , e);
//            throw new TokenException("Token已过期, ");
//        } catch (UnsupportedJwtException e) {
//            logger.error("Token格式错误: {} " , e);
//            throw new TokenException("Token格式错误");
//        } catch (MalformedJwtException e) {
//            logger.error("Token没有被正确构造: {} " , e);
//            throw new TokenException("Token没有被正确构造");
//        } catch (SignatureException e) {
//            logger.error("签名失败: {} " , e);
//            throw new ("签名失败");
//        } catch (IllegalArgumentException e) {
//            logger.error("非法参数异常: {} " , e);
//            throw new TokenException("非法参数异常");
        } catch (Exception e) {
            logger.error("解析token错误, 请重新登录: {} ", e);
            // 清除session
            request.getSession().setAttribute(JwtUtil.SESSION_TOKEN, null);
            throw new RuntimeException("token已过期,请重新登录!");
        }
    }

    /**
     * 校验token是否正确
     *
     * @param request  request
     * @param response response
     * @return Claims
     */
    public static Claims check(HttpServletRequest request, HttpServletResponse response) {
        // a标签问题
        HttpSession session = request.getSession();
        Object sessionToken = session.getAttribute(SESSION_TOKEN);
        if (sessionToken != null) {
            return parseToken(String.valueOf(sessionToken), request, response);
        }

        // 正常的请求头校验
        String header = request.getHeader("Authorization");
        if (header == null || !header.startsWith(BEARER)) {
            logger.info("check Token为空");
            return null;
        }
        return parseToken(header.replace("Bearer ", ""), request, response);
    }

    /**
     * 根据用户名密码生成token
     *
     * @param username 用户名
     * @param password 密码
     * @return String
     */
    public static String createToken(String username, String password) {
        String token = null;
        try {
            long nowMillis = System.currentTimeMillis();
            Date now = new Date(nowMillis);
            long expMillis = nowMillis + EXPIRATION;
            Date exp = new Date(expMillis);

            token = Jwts.builder()
                    .setIssuer(username).setAudience(password)
                    //签发时间
                    .setIssuedAt(now)
                    //过期时间
                    .setExpiration(exp)
                    //采用什么算法是可以自己选择的,不一定非要采用HS512
                    .signWith(SignatureAlgorithm.HS512, SIGNING_KEY)
                    .compact();
            // 生成token end
        } catch (Exception e) {
            e.printStackTrace();
        }
        return token;
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/116387.html

(0)
Java光头强的头像Java光头强

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!