jwt 多字段 加密 和解析

代码主要是从这里来的 稍微改了一下, 之前不知道 可以 setClaims 放map,摸索出来的
https://gitee.com/SnailClimb/spring-security-jwt-guide


//import github.javaguide.springsecurityjwtguide.security.common.constants.SecurityConstants;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.SerializationException;
import io.jsonwebtoken.io.Serializer;
import io.jsonwebtoken.security.Keys;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;


import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 
 * @author shuang.kou
 * @description JWT工具类
 */
public class JwtTokenUtils {


    /**
     * 生成足够的安全随机密钥,以适合符合规范的签名
     */
    private static final byte[] API_KEY_SECRET_BYTES = DatatypeConverter.parseBase64Binary(SecurityConstants.JWT_SECRET_KEY);
    private static final SecretKey SECRET_KEY = Keys.hmacShaKeyFor(API_KEY_SECRET_BYTES);

    public static String createToken(String username, String id, List<String> roles, boolean isRememberMe) {
//        return createToken( username,  id,  roles,  isRememberMe,null);
        long expiration = isRememberMe ? SecurityConstants.EXPIRATION_REMEMBER : SecurityConstants.EXPIRATION;
        final Date createdDate = new Date();
        final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);

//        Serializer<Map<String, String>> serializer = new Serializer<Map<String, String>>() {
//            @Override
//            public byte[] serialize(Map<String, String> stringStringMap) throws SerializationException {
//                return new byte[0];
//            }
//        }

//                .withClaim("userid", userid)
//                .withClaim("companyid", companyid)
//                .withClaim("role", role)
        Map<String, Object> claimsMap = new HashMap<>();
//        .withClaim("userid", userid)
//                .withClaim("companyid", companyid)
//                .withClaim("role", role)
        claimsMap.put("role", String.join(",", roles));
//        claimsMap.put("userId", id);
//这个id 其实可以 放在 setid 里面 ,应该可以拿到的
        claimsMap.put("companyId", "1");
        String tokenPrefix = Jwts.builder()
                .setHeaderParam("type", SecurityConstants.TOKEN_TYPE)
                .signWith(SECRET_KEY, SignatureAlgorithm.HS256)
//                .claim(SecurityConstants.ROLE_CLAIMS, String.join(",", roles))
//                要申请多个东西 就在这里配置
                .setClaims(claimsMap)
                .setId(id)
                .setIssuer("SnailClimb")
                .setIssuedAt(createdDate)
                .setSubject(username)
//                这个应该和 withClaim  是一个意思吧 ,但是 withClaim 是给个字段名
//                这里是给个值,withClaim 给的是 key
//                .setSubject("haha")
//                .setSubject("dahidhai")
//                .setPayload()
//                怎么用
//                对了 string 就是万物,string当作 json之类的用就行了
//                .serializeToJsonWith()

//                多设置 会覆盖的
                .setExpiration(expirationDate)
                .compact();
        return SecurityConstants.TOKEN_PREFIX + tokenPrefix; // 添加 token 前缀 "Bearer ";
    }

    public static String createToken(String username, String id, List<String> roles, boolean isRememberMe,
                                     String companyId) {
        long expiration = isRememberMe ? SecurityConstants.EXPIRATION_REMEMBER : SecurityConstants.EXPIRATION;
        final Date createdDate = new Date();
        final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);

//        Serializer<Map<String, String>> serializer = new Serializer<Map<String, String>>() {
//            @Override
//            public byte[] serialize(Map<String, String> stringStringMap) throws SerializationException {
//                return new byte[0];
//            }
//        }

//                .withClaim("userid", userid)
//                .withClaim("companyid", companyid)
//                .withClaim("role", role)
        Map<String, Object> claimsMap = new HashMap<>();
//        .withClaim("userid", userid)
//                .withClaim("companyid", companyid)
//                .withClaim("role", role)
        claimsMap.put("role", String.join(",", roles));
//        claimsMap.put("userId", id);
//这个id 其实可以 放在 setid 里面 ,应该可以拿到的
        claimsMap.put("companyId", companyId);
        String tokenPrefix = Jwts.builder()
                .setHeaderParam("type", SecurityConstants.TOKEN_TYPE)
                .signWith(SECRET_KEY, SignatureAlgorithm.HS256)
//                .claim(SecurityConstants.ROLE_CLAIMS, String.join(",", roles))
//                要申请多个东西 就在这里配置
                .setClaims(claimsMap)
                .setId(id)
                .setIssuer("SnailClimb")
                .setIssuedAt(createdDate)
                .setSubject(username)
//                这个应该和 withClaim  是一个意思吧 ,但是 withClaim 是给个字段名
//                这里是给个值,withClaim 给的是 key
//                .setSubject("haha")
//                .setSubject("dahidhai")
//                .setPayload()
//                怎么用
//                对了 string 就是万物,string当作 json之类的用就行了
//                .serializeToJsonWith()

//                多设置 会覆盖的
                .setExpiration(expirationDate)
                .compact();
        return SecurityConstants.TOKEN_PREFIX + tokenPrefix; // 添加 token 前缀 "Bearer ";
    }

    /**
     * @param id
     * @param username
     * @param tokenNeedMap 设置 roles comid
     * @param isRememberMe
     * @return
     */
    public static String createToken(String id, String username, Map<String, Object> tokenNeedMap,

                                     boolean isRememberMe
    ) {
        long expiration = isRememberMe ? SecurityConstants.EXPIRATION_REMEMBER : SecurityConstants.EXPIRATION;
        final Date createdDate = new Date();
        final Date expirationDate = new Date(createdDate.getTime() + expiration * 1000);

//        Serializer<Map<String, String>> serializer = new Serializer<Map<String, String>>() {
//            @Override
//            public byte[] serialize(Map<String, String> stringStringMap) throws SerializationException {
//                return new byte[0];
//            }
//        }

//                .withClaim("userid", userid)
//                .withClaim("companyid", companyid)
//                .withClaim("role", role)
//        Map<String, Object> claimsMap = new HashMap<>();
//        .withClaim("userid", userid)
//                .withClaim("companyid", companyid)
//                .withClaim("role", role)
//        claimsMap.put("role", String.join(",", roles));
//        claimsMap.put("userId", id);
//这个id 其实可以 放在 setid 里面 ,应该可以拿到的
//        claimsMap.put("companyId", companyId);
        String tokenPrefix = Jwts.builder()
                .setHeaderParam("type", SecurityConstants.TOKEN_TYPE)
                .signWith(SECRET_KEY, SignatureAlgorithm.HS256)
//                .claim(SecurityConstants.ROLE_CLAIMS, String.join(",", roles))
//                要申请多个东西 就在这里配置
                .setClaims(tokenNeedMap)
                .setId(id)
                .setIssuer("SnailClimb")
                .setIssuedAt(createdDate)
                .setSubject(username)
//                这个应该和 withClaim  是一个意思吧 ,但是 withClaim 是给个字段名
//                这里是给个值,withClaim 给的是 key
//                .setSubject("haha")
//                .setSubject("dahidhai")
//                .setPayload()
//                怎么用
//                对了 string 就是万物,string当作 json之类的用就行了
//                .serializeToJsonWith()

//                多设置 会覆盖的
                .setExpiration(expirationDate)
                .compact();
        return SecurityConstants.TOKEN_PREFIX + tokenPrefix; // 添加 token 前缀 "Bearer ";
    }

    public static String getId(String token) {
        Claims claims = getClaims(token);
//        System.out.println("claims");
//        System.out.println(claims);
        return claims.getId();
    }

    public static UsernamePasswordAuthenticationToken getAuthentication(String token) {
        Claims claims = getClaims(token);
        List<SimpleGrantedAuthority> authorities = getAuthorities(claims);
        String userName = claims.getSubject();
        return new UsernamePasswordAuthenticationToken(userName, token, authorities);
    }

    private static List<SimpleGrantedAuthority> getAuthorities(Claims claims) {
        String role = (String) claims.get(SecurityConstants.ROLE_CLAIMS);
        return Arrays.stream(role.split(","))
                .map(SimpleGrantedAuthority::new)
                .collect(Collectors.toList());
    }

    //    但是不知道怎么从 token 里解析出东西了
    private static Claims getClaims(String token) {
        return Jwts.parser()
                .setSigningKey(SECRET_KEY)
                .parseClaimsJws(token)
                .getBody();
    }

    public static void main(String[] args) {
        List<String> roles = new ArrayList<>();
        roles.add("admin");

        String tokenWithPrefix = createToken("starplatinum", "1", roles, true);
        System.out.println("tokenWithPrefix");
        System.out.println(tokenWithPrefix);
        String tokenNoPrefix = tokenWithPrefix.replace(SecurityConstants.TOKEN_PREFIX, "");

        String id = getId(tokenNoPrefix);
        Claims claims = getClaims(tokenNoPrefix);
        System.out.println("id");
        System.out.println(id);
        System.out.println("claims");
        System.out.println(claims);
        Object companyId = claims.get("companyId");
        Object role = claims.get("role");
        System.out.println("companyId");
        System.out.println(companyId);
        System.out.println("role");
        System.out.println(role);
//        claims
//        {ROLE_=admin, jti=1, iss=SnailClimb, iat=1627563401, sub=dahidhai, exp=1628168201}
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值