亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring Boot詳解整合JWT教程

 更新時(shí)間:2022年07月05日 08:54:13   作者:陳寶子  
JWT是目前比較流行的跨域認(rèn)證解決方案,本文主要介紹了SpringBoot整合JWT的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

1、概述

JWT 簡(jiǎn)稱 JSON Web Token,也就是通過(guò)JSON形式作為Web應(yīng)用中的令牌,用于各方之間安全地將信息作為JSON對(duì)象傳輸,在數(shù)據(jù)傳輸?shù)倪^(guò)程中還可以完成數(shù)據(jù)加密、簽名等相關(guān)處理。

2、優(yōu)勢(shì)所在

在JavaWeb階段,經(jīng)常使用session來(lái)存儲(chǔ),以方便用來(lái)判斷用戶是否操作等等。但這又恰巧暴露了一個(gè)問(wèn)題,用session存儲(chǔ)是需要占用服務(wù)器內(nèi)存的。當(dāng)用戶只有一兩個(gè)的時(shí)候沒(méi)什么問(wèn)題,但是當(dāng)用戶成千上萬(wàn)的話,服務(wù)器就很難招架得住了。并且session是基于cookie來(lái)實(shí)現(xiàn)的,因此數(shù)據(jù)很容易被截獲,遭遇CSRF跨域偽造攻擊,因此不太安全。這時(shí)JWT的優(yōu)勢(shì)就突顯出來(lái)的:

  • 簡(jiǎn)潔(Compact): 可以通過(guò)URL,POST參數(shù)或者在HTTP header發(fā)送,因?yàn)閿?shù)據(jù)量小,傳輸速度也很快
  • 自包含(Self-contained):負(fù)載中包含了所有用戶所需要的信息,避免了多次查詢數(shù)據(jù)庫(kù)
  • 因?yàn)門oken是以JSON加密的形式保存在客戶端的,所以JWT是跨語(yǔ)言的,原則上任何web形式都支持。
  • 不需要在服務(wù)端保存會(huì)話信息,特別適用于分布式微服務(wù)。

3、結(jié)構(gòu)組成

JWT 中的 token 組成主要有三部分:

  • 標(biāo)頭(Header)
  • 有效載荷(Payload)
  • 簽名(Signature)

3.1、標(biāo)頭(Header)

標(biāo)頭通常由兩部分組成:令牌的類型 ( 即JWT ) 和所使用的簽名算法,例如HMAC SHA256(默認(rèn))或RSA。它會(huì)使用Base64編碼組成JWT結(jié)構(gòu)的第一部分。值得注意的是,Base64是一種編碼,也就是說(shuō),它是可以被翻譯回原來(lái)的樣子的,它并不是一種加密過(guò)程。

{
  "alg": "HS256",
  "typ": "JWT"
}

3.2、有效負(fù)載(Payload)

有效負(fù)荷是包含聲明,通常將需要傳遞的數(shù)據(jù)存放在Payload中,同樣的是使用Base64編碼,但這同時(shí)說(shuō)明這一塊是可以被反編譯的,這是什么意思呢?就是太敏感的信息存放在這里的話存在被捕獲的可能,因此官方推薦在Payload中不要存放敏感的信息,例如女生的年齡。

3.3、簽名(Signature)

簽名是由編碼后的標(biāo)頭和有效負(fù)荷以及我們提供的一個(gè)密鑰,然后使用標(biāo)頭規(guī)定的簽名算法進(jìn)行簽名。因此,簽名的主要作用是保證JWT沒(méi)有被篡改過(guò),保證 token 的合法性。

這里特別注意的是,密鑰 secret 是驗(yàn)證 token 是否合法的重要憑證,如果用于驗(yàn)證的密鑰被外界所獲取到的話,我們所建立的驗(yàn)證防線將如同虛設(shè)!

4、Spring boot整合JWT 導(dǎo)入依賴

<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.19.0</version>
</dependency>

編寫JwtUtils,提高代碼的重用率

public class JwtUtils {
    /** 過(guò)期時(shí)間,單位:秒,默認(rèn)半小時(shí)過(guò)期 **/
    private static final long EXPIRATION = 60 * 30L;
    /** 密鑰,一般長(zhǎng)度較長(zhǎng),內(nèi)容較復(fù)雜 **/
    private static final String SECRET = "my_secret";
    /**
     * @description 創(chuàng)建token
     * @author xBaozi
     * @date 20:49 2022/3/31
     **/
    public static String createToken(Map<String, String> claimMap) {
        // 當(dāng)前時(shí)間戳加上設(shè)定的毫秒數(shù)(1秒 == 1000毫秒)
        Date expiration = new Date(System.currentTimeMillis() + EXPIRATION * 1000);
        // 設(shè)置JWT頭部
        Map<String, Object> map = new HashMap<>();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        // 創(chuàng)建token
        JWTCreator.Builder builder = JWT.create();
        //使用Lambda創(chuàng)建payload
        claimMap.forEach((k,v)->{
            builder.withClaim(k,v);
        });
        // 添加頭部,可省略保持默認(rèn),默認(rèn)即map中的鍵值對(duì)
        return builder.withHeader(map)
                // 設(shè)置過(guò)期時(shí)間
                .withExpiresAt(expiration)
                // 設(shè)置簽名解碼算法
                .sign(Algorithm.HMAC256(SECRET));
    }
    /**
     * @description 驗(yàn)證token
     * @author xBaozi
     * @date 23:36 2022/3/31
     **/
    public static DecodedJWT verifyToken(String token) {
        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }
}

編寫過(guò)濾器,這是為了使得不用在每一個(gè)controller前端控制器都寫一遍獲取token,將token放在請(qǐng)求體中請(qǐng)求,從而簡(jiǎn)化開(kāi)發(fā)操作

public class JwtInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Map<String, Object> map = new HashMap<>();
        //獲取請(qǐng)求頭中令牌
        String token = request.getHeader("token");
        try {
            //驗(yàn)證令牌
            JwtUtils.verifyToken(token);
            //驗(yàn)證成功,放行請(qǐng)求
            return true;
        } catch (SignatureVerificationException e) {
            e.printStackTrace();
            map.put("msg", "無(wú)效簽名!");
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            map.put("msg", "token過(guò)期!");
        } catch (AlgorithmMismatchException e) {
            e.printStackTrace();
            map.put("msg", "token算法不一致!");
        } catch (Exception e) {
            e.printStackTrace();
            map.put("msg", "token無(wú)效!!");
        }
        //設(shè)置狀態(tài)
        map.put("state", false);
        //將map轉(zhuǎn)為json
        String json = new ObjectMapper().writeValueAsString(map);
        // 相應(yīng)json數(shù)據(jù)
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().println(json);
        return false;
    }
}

配置過(guò)濾器

@Configuration
public class JwtConfig implements WebMvcConfigurer{
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new JwtInterceptor())
                    //添加攔截路徑
                    .addPathPatterns("/**")
                    //添加放行路徑
                    .excludePathPatterns("/user/login");
        }
}

編寫前端控制器,這里以兩個(gè)為例

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
    // 這里只做演示,就不寫Service層了
    // @Autowired
    // private UserService userService;
    /**
     * @description 登錄功能
     * @author xBaozi
     * @date 0:02 2022/4/1
     * @param user  user對(duì)象,默認(rèn)有值
     **/
    @GetMapping("/login")
    public Map<String,Object> login(User user){
        log.info("用戶名: [{}]",user.getName());
        log.info("密碼: [{}]",user.getPassword());
        Map<String, Object> map = new HashMap<>();
        try{
            Map<String,String> payload =  new HashMap<>();
            payload.put("id",user.getId());
            payload.put("name",user.getName());
            // 生成JWT的令牌
            String token = JwtUtils.createToken(payload);
            map.put("state",true);
            map.put("msg","認(rèn)證成功");
            // 響應(yīng)token
            map.put("token",token);
        }catch (Exception e){
            map.put("state",false);
            map.put("msg",e.getMessage());
        }
        return map;
    }
    @PostMapping("/other")
    public Map<String,Object> test(HttpServletRequest request){
        Map<String, Object> map = new HashMap<>();
        //處理自己業(yè)務(wù)邏輯
        String token = request.getHeader("token");
        DecodedJWT verify = JwtUtils.verifyToken(token);
        log.info("用戶id: [{}]",verify.getClaim("id").asString());
        log.info("用戶name: [{}]",verify.getClaim("name").asString());
        map.put("state",true);
        map.put("msg","請(qǐng)求成功!");
        return map;
    }
}

postman測(cè)試

IDEA控制臺(tái)查看信息

搞完收工,這里的token交由前端進(jìn)行管理保存?。?!溜了~

到此這篇關(guān)于Spring Boot詳解整合JWT教程的文章就介紹到這了,更多相關(guān)Spring Boot JWT內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)自定義指標(biāo)監(jiān)控功能

    SpringBoot實(shí)現(xiàn)自定義指標(biāo)監(jiān)控功能

    本文主要介紹了SpringBoot實(shí)現(xiàn)自定義指標(biāo)監(jiān)控功能的實(shí)現(xiàn),,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,感興趣的小伙伴跟著著小編來(lái)一起來(lái)學(xué)習(xí)吧
    2024-01-01
  • java應(yīng)用開(kāi)發(fā)之JVM運(yùn)行時(shí)內(nèi)存分析

    java應(yīng)用開(kāi)發(fā)之JVM運(yùn)行時(shí)內(nèi)存分析

    這篇文章主要介紹了java應(yīng)用開(kāi)發(fā)之JVM運(yùn)行時(shí)內(nèi)存,文中附含圖文示例內(nèi)容分析非常簡(jiǎn)要,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-09-09
  • 為什么JDK8中HashMap依然會(huì)死循環(huán)

    為什么JDK8中HashMap依然會(huì)死循環(huán)

    這篇文章主要介紹了為什么JDK8中HashMap依然會(huì)死循環(huán),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • java實(shí)現(xiàn)單鏈表中的增刪改

    java實(shí)現(xiàn)單鏈表中的增刪改

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)單鏈表中的增刪改,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • Mybatis中l(wèi)ike搭配concat的寫法詳解

    Mybatis中l(wèi)ike搭配concat的寫法詳解

    這篇文章主要介紹了Mybatis中l(wèi)ike搭配concat的寫法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 關(guān)于JWT之token令牌認(rèn)證登錄

    關(guān)于JWT之token令牌認(rèn)證登錄

    這篇文章主要介紹了關(guān)于JWT之token令牌認(rèn)證登錄,使用JWT能夠保證Token的安全性,且能夠進(jìn)行Token時(shí)效性的檢驗(yàn),使用JWT時(shí),登錄成功后將用戶信息生成一串令牌字符串,需要的朋友可以參考下
    2023-05-05
  • 解決mybatis三表連接查詢數(shù)據(jù)重復(fù)的問(wèn)題

    解決mybatis三表連接查詢數(shù)據(jù)重復(fù)的問(wèn)題

    這篇文章主要介紹了解決mybatis三表連接查詢數(shù)據(jù)重復(fù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • 詳解Jmeter線程組的設(shè)置方法

    詳解Jmeter線程組的設(shè)置方法

    本文主要介紹了Jmeter線程組的設(shè)置方法,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Spring Cloud Gateway全局異常處理的方法詳解

    Spring Cloud Gateway全局異常處理的方法詳解

    這篇文章主要給大家介紹了關(guān)于Spring Cloud Gateway全局異常處理的相關(guān)資料,需要的朋友可以參考下
    2018-10-10
  • idea Gradle 控制臺(tái)中文亂碼的解決

    idea Gradle 控制臺(tái)中文亂碼的解決

    通過(guò)IDEA執(zhí)行g(shù)radle的任務(wù)時(shí),在終端的輸出出現(xiàn)中文亂碼,本文主要介紹了idea Gradle 控制臺(tái)中文亂碼的解決,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03

最新評(píng)論