溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JAVA中JWT怎么創(chuàng)建token

發(fā)布時(shí)間:2021-11-17 11:40:17 來(lái)源:億速云 閱讀:152 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“JAVA中JWT怎么創(chuàng)建token”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“JAVA中JWT怎么創(chuàng)建token”吧!

JSON Web Token(縮寫 JWT)是目前最流行的跨域認(rèn)證解決方案。
JWT 的三個(gè)部分依次如下
Header(頭部):是一個(gè) JSON 對(duì)象,描述 JWT 的元數(shù)據(jù){ "alg": "HS256", typ": "JWT" }
Payload(負(fù)載):也是一個(gè) JSON 對(duì)象,用來(lái)存放實(shí)際需要傳遞的數(shù)據(jù),JWT 規(guī)定了7個(gè)官方字段:
    iss (issuer):簽發(fā)人
    exp (expiration time):過(guò)期時(shí)間
    sub (subject):主題
    aud (audience):受眾
    nbf (Not Before):生效時(shí)間
    iat (Issued At):簽發(fā)時(shí)間
    jti (JWT ID):編號(hào)
Signature(簽名):對(duì)前兩部分的簽名,防止數(shù)據(jù)篡改

1.JWT中Header頭和Payload有效載荷序列化的算法都用到了Base64URL,簽名哈希部分是對(duì)Header與Payload兩部分?jǐn)?shù)據(jù)簽名
2.客戶端接收服務(wù)器返回的JWT,將其存儲(chǔ)在Cookie或localStorage中,客戶端將在與服務(wù)器交互中都會(huì)帶JWT,將它放入HTTP請(qǐng)求的Header Authorization字段中
3.JWT的最大缺點(diǎn)是服務(wù)器不保存會(huì)話狀態(tài),所以在使用期間不可能取消令牌或更改令牌的權(quán)限
4.JWT本身包含認(rèn)證信息,因此一旦信息泄露,任何人都可以獲得令牌的所有權(quán)限
5.JWT不建議使用HTTP協(xié)議來(lái)傳輸代碼,而是使用加密的HTTPS協(xié)議進(jìn)行傳輸

pom.xml引入依賴包

<!-- JWT Token驗(yàn)證機(jī)制 -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.8.1</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.0</version>
</dependency>

工具類

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.SignatureVerificationException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import org.apache.commons.lang3.time.DateUtils;

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

/**
 * @Description JWT跨域管理token工具類
 * @Author JL
 * @Date 2019/08/08
 * @Version V1.0
 */
public class JwtTokenUtils {


    /**
     * 加密密鑰
     */
    private static final String SECRET = "wNmx01w27MQnPc3BtUQkty_23P0pVlAdj86o5XznUrE";

    /**
     * jwt創(chuàng)建token,考慮安全性,token中不因該放入太多信息(勿放密碼之類的敏感信息),只放入關(guān)鍵字段值即可,如用戶ID
     * @param sub     主題(可以放入關(guān)鍵數(shù)據(jù),如:userid, 用戶唯一值等)
     * @param timeout 過(guò)期時(shí)長(zhǎng)(秒)
     * @return
     */
    public static String createToken(String sub, int timeout) {
        JWTCreator.Builder builder = JWT.create();
        builder.withSubject(sub);//主題
        builder.withIssuer("pro-server");
        builder.withExpiresAt(DateUtils.addSeconds(new Date(), timeout));//過(guò)期時(shí)間,30秒后過(guò)期
        String jwtToken = builder.sign(Algorithm.HMAC256(SECRET));
        return jwtToken;
    }

    /**
     * 對(duì)jwt創(chuàng)建的token進(jìn)行驗(yàn)簽與解析,返回Subject(主題)中存放的內(nèi)容
     * @param token
     * @return
     * @throws TokenExpiredException          會(huì)話超時(shí)異常
     * @throws SignatureVerificationException 驗(yàn)簽無(wú)效異常
     */
    public static String parseToken(String token) throws TokenExpiredException, SignatureVerificationException {
        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getSubject();
    }

    /**
     * jwt創(chuàng)建token,考慮安全性,token中不因該放入太多信息(勿放密碼之類的敏感信息)
     * @param loadMap   數(shù)據(jù)集合
     * @param timeout   過(guò)期時(shí)長(zhǎng)(秒)
     * @return
     */
    public static String createToken(Map<String, Object> loadMap, int timeout) {
        JWTCreator.Builder builder = JWT.create();
        loadMap.forEach((k, v) -> {
            if (v instanceof String) {
                builder.withClaim(k, (String) v);
            } else if (v instanceof Date) {
                builder.withClaim(k, (Date) v);
            } else if (v instanceof Long) {
                builder.withClaim(k, (Long) v);
            } else if (v instanceof Integer) {
                builder.withClaim(k, (Integer) v);
            } else if (v instanceof Boolean) {
                builder.withClaim(k, (Boolean) v);
            }
        });
        builder.withIssuer("pro-server");
        builder.withExpiresAt(DateUtils.addSeconds(new Date(), timeout));//過(guò)期時(shí)間,30秒后過(guò)期
        String jwtToken = builder.sign(Algorithm.HMAC256(SECRET));
        return jwtToken;
    }

    /**
     * 對(duì)jwt創(chuàng)建的token進(jìn)行驗(yàn)簽與解析,返回集合
     * @param token
     * @return
     * @throws TokenExpiredException          會(huì)話超時(shí)異常
     * @throws SignatureVerificationException 驗(yàn)簽無(wú)效異常
     */
    public static Map<String, Object> parseTokenToMap(String token) throws TokenExpiredException, SignatureVerificationException {
        Map<String, Claim> claimMap = JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token).getClaims();
        if (claimMap == null){
            return null;
        }
        Map<String, Object> loadMap = new HashMap<>();
        claimMap.forEach((k, v) -> {
            Object obj = null;
            if (v.asString() != null) {
                obj = v.asString();
            } else if (v.asBoolean() != null) {
                obj = v.asBoolean();
            } else if (v.asDate() != null || v.asLong() != null) {//Date類型按Long方式來(lái)處理
                obj = v.asLong();
            } else if (v.asInt() != null) {
                obj = v.asInt();
            }
            loadMap.put(k, obj);
        });
        return loadMap;
    }

    //測(cè)試方法
    //登錄成功后,將用戶的id放入到JwtTokenUtils.createToken(userid, 60 * 30);
    //每次請(qǐng)求在攔截器或過(guò)濾器中,獲取請(qǐng)求中的token調(diào)用JwtTokenUtils.parseToken(jwtToken)驗(yàn)證是否有效,或從token中獲取userid進(jìn)行業(yè)務(wù)邏輯操作
    public static void main(String[] args) {
        //創(chuàng)建token和解析token
        String subject = "userid_001";
        System.out.println("新建subject = " + subject);
        String jwtToken = JwtTokenUtils.createToken(subject, 60);
        System.out.println("生成token = " + jwtToken);
        try {
            subject = JwtTokenUtils.parseToken(jwtToken);
            System.out.println("解析subject = " + subject);
        } catch(TokenExpiredException tee){
            throw new TokenExpiredException("token已過(guò)有效期,請(qǐng)重新申請(qǐng):" + tee.getMessage());
        } catch(SignatureVerificationException sve){
            //驗(yàn)證簽名不通過(guò)(數(shù)據(jù)被篡改過(guò))
            throw sve;
        }

        //過(guò)期測(cè)試
//        String jwtToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyaWRfMDAxIiwiaXNzIjoicHJvLXNlcnZlciIsImV4cCI6MTU2NTI0OTMxMH0.0cSnHLHTqDx-FXoL08yk6AtIwobiWcMNRofyE4dunGY";
//        subject = JwtTokenUtils.parseToken(jwtToken);

        //無(wú)效驗(yàn)鑒(將最后一位更改為z)
//        String jwtToken = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyaWRfMDAxIiwiaXNzIjoicHJvLXNlcnZlciIsImV4cCI6MTU2NTI0OTMxMH0.0cSnHLHTqDx-FXoL08yk6AtIwobiWcMNRofyE4dunGz";
//        subject = JwtTokenUtils.parseToken(jwtToken);


        //將多種數(shù)據(jù)放入集合中,通過(guò)jwt創(chuàng)建token
        /*
        Map<String, Object> loadMap = new HashMap<>();
        loadMap.put("userId", (Long) 1000000L);
        loadMap.put("userName", "test");
        loadMap.put("isLogin", true);
        String jwtToken = JwtTokenUtils.createToken(loadMap, 60);
        System.out.println(jwtToken);

        Map<String, Object> loadMap2 = JwtTokenUtils.parseTokenToMap(jwtToken);
        for (Map.Entry<String, Object> entry : loadMap2.entrySet()) {
            System.out.println(entry.getKey() + "=" + entry.getValue());
        }
        */
    }
}

請(qǐng)求中集成使用

1.登錄成功后,將用戶的id放入到JwtTokenUtils.createToken(userid, 60 * 30);
2.對(duì)需要鑒權(quán)的每次URL請(qǐng)求在攔截器或過(guò)濾器中處理,獲取請(qǐng)求中的token(一般放在請(qǐng)求頭部,每次請(qǐng)求必帶)調(diào)用JwtTokenUtils.parseToken(jwtToken)驗(yàn)證是否有效,或從token中獲取userid進(jìn)行業(yè)務(wù)邏輯操作

到此,相信大家對(duì)“JAVA中JWT怎么創(chuàng)建token”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI