Jwt工具类,生成token和解析token,直接用

依赖

<!--        jwt -->
         <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt-api</artifactId>
            <version>0.11.2</version>
        </dependency>

工具类

/**
 * JWT工具类
 */
public class ApiToken implements Serializable {

	private static final long serialVersionUID = 1L;

	/**
	 * JWT签名加密key
	 */
	private final static String JWT_SIGN_KEY = "fddc1534226xxxxxb4594dc5sd56a41s";

	/**
	 * 获取请求token
	 *
	 * @param request
	 * @return
	 */
	public static String getToken(HttpServletRequest request) {
		String token = request.getHeader("Authorization");
		String tokenHead = "Bearer ";
		if (token == null) {
			token = request.getHeader("accessToken");
		} else if (token.contains(tokenHead)) {
			token = token.substring(tokenHead.length());
		}
		if ("".equals(token)) {
			token = null;
		}
		return token;
	}

	/**
	 * 获取用户名
	 * 
	 * @return
	 */
	public static String getUsername() {
		String username = null;
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
		String header = getToken(request);
		if (StringUtils.isNotBlank(header)) {
			// 解析token
			Claims claims = Jwts.parser().setSigningKey(JWT_SIGN_KEY).parseClaimsJws(header.replace(SecurityConstant.TOKEN_SPLIT, "")).getBody();
			username = claims.getSubject();
		}
		return username;
	}

	/**
	 * 生成token
	 * 
	 * @param username
	 * @return
	 */
	public static String genToken(String username) {
		// 登陆成功生成token
		String token = SecurityConstant.TOKEN_SPLIT + Jwts.builder()
				// 主题 放入用户名
				.setSubject(username)
				// 失效时间
				.setExpiration(new Date(System.currentTimeMillis() + 3600 * 12 * 1000))
				// 签名算法和密钥
				.signWith(SignatureAlgorithm.HS512, JWT_SIGN_KEY).compact();
		return token;
	}
}
/**
 * Jwt配置
 */
@Configuration
public class JwtAuthenticationConfig {

	@SuppressWarnings({ "rawtypes", "unchecked" })
	@Bean
	public FilterRegistrationBean jwtFilter() {
		final FilterRegistrationBean registrationBean = new FilterRegistrationBean();
		JwtAuthenticationFilter filter = new JwtAuthenticationFilter();
		registrationBean.setFilter(filter);
		return registrationBean;
	}

}
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

@Slf4j
@Component
//@ConfigurationProperties(prefix = "jwt")
public class JwtUtil {
    /**
     * 携带JWT令牌的HTTP的Header的名称,在实际生产中可读性越差越安全
     */
//    @Getter
//    @Value("${jwt.header}")
    private String header = "Authorization";

    /**
     * 为JWT基础信息加密和解密的密钥
     * 在实际生产中通常不直接写在配置文件里面。而是通过应用的启动参数传递,并且需要定期修改。
     */
//    @Value("${jwt.secret}")
    private String secret = "guYloAPAmKwvKq4a5f5dqnifiQatxMEPNOvtwPsJPQWLNKJDCXZ";

    /**
     * JWT令牌的有效时间,单位秒
     * - 默认1周
     */
//    @Value("${jwt.expiration}")
    private Long expiration = 604800L;

    /**
     * SecretKey 根据 SECRET 的编码方式解码后得到:
     * Base64 编码:SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64.decode(secretString));
     * Base64URL 编码:SecretKey key = Keys.hmacShaKeyFor(Decoders.BASE64URL.decode(secretString));
     * 未编码:SecretKey key = Keys.hmacShaKeyFor(secretString.getBytes(StandardCharsets.UTF_8));
     */
    private static SecretKey getSecretKey(String secret) {
        byte[] encodeKey = Decoders.BASE64.decode(secret);
        return Keys.hmacShaKeyFor(encodeKey);
    }

    /**
     * 用claims生成token
     *
     * @param claims 数据声明,用来创建payload的私有声明
     * @return token 令牌
     */
    private String generateToken(Map<String, Object> claims) {
        SecretKey key = getSecretKey(secret);
        //SecretKey key = Keys.secretKeyFor(SignatureAlgorithm.HS256); //两种方式等价

        // 添加payload声明
        JwtBuilder jwtBuilder = Jwts.builder()
                // 如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
                .setClaims(claims)
                // 设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
                .setId(UUID.randomUUID().toString())
                // iat: jwt的签发时间
                .setIssuedAt(new Date())

                // 你也可以改用你喜欢的算法,支持的算法详见:https://github.com/jwtk/jjwt#features
                // SignatureAlgorithm.HS256:指定签名的时候使用的签名算法,也就是header那部分
                .signWith(SignatureAlgorithm.HS256, key)
                .setExpiration(new Date(System.currentTimeMillis() + this.expiration * 1000));

        String token = jwtBuilder.compact();
        return token;
    }

    /**
     * 生成Token令牌
     *
     * @param userDetails 用户
     * @param id          用户编号
     * @return 令牌Token
     */
    public  String generateToken(UserDetails userDetails, String id) {
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId", id);
        claims.put("sub", userDetails.getUsername());
        claims.put("created", new Date());
        return generateToken(claims);
    }

    /**
     * 从token中获取数据声明claim
     *
     * @param token 令牌token
     * @return 数据声明claim
     */
    public Claims getClaimsFromToken(String token) {
        try {
            SecretKey key = getSecretKey(secret);
            Claims claims = Jwts.parser()
                    .setSigningKey(key)
                    .parseClaimsJws(token)
                    .getBody();
            return claims;
        } catch (ExpiredJwtException | UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
            log.error("token解析错误", e);
            throw new IllegalArgumentException("Token invalided.");
        }
    }

    public String getUserId(String token) {
        return (String) getClaimsFromToken(token).get("userId");
    }

    /**
     * 从token中获取登录用户名
     *
     * @param token 令牌
     * @return 用户名
     */
    public String getSubjectFromToken(String token) {
        String subject;
        try {
            Claims claims = getClaimsFromToken(token);
            subject = claims.getSubject();
        } catch (Exception e) {
            subject = null;
        }
        return subject;
    }


    /**
     * 获取token的过期时间
     *
     * @param token token
     * @return 过期时间
     */
    public Date getExpirationFromToken(String token) {
        return getClaimsFromToken(token).getExpiration();
    }

    /**
     * 判断token是否过期
     *
     * @param token 令牌
     * @return 是否过期:已过期返回true,未过期返回false
     */
    public Boolean isTokenExpired(String token) {
        Date expiration = getExpirationFromToken(token);
        return expiration.before(new Date());
    }

    /**
     * 验证令牌:判断token是否非法
     *
     * @param token       令牌
     * @param userDetails 用户
     * @return 如果token未过期且合法,返回true,否则返回false
     */
    public Boolean validateToken(String token, UserDetails userDetails) {
        //如果已经过期返回false
        if (isTokenExpired(token)) {
            return false;
        }
        String usernameFromToken = getSubjectFromToken(token);
        String username = userDetails.getUsername();
        return username.equals(usernameFromToken);
    }

}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值