最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot整合JWT的入門(mén)指南

 更新時(shí)間:2021年06月29日 11:32:07   作者:一位不透露姓名的先生  
JWT全稱(chēng)是json web token,它將用戶信息加密到 token 里,服務(wù)器不保存任何用戶信息,服務(wù)器通過(guò)使用保存的密鑰驗(yàn)證 token 的正確性,只要正確即通過(guò)驗(yàn)證,這篇文章主要給大家介紹了關(guān)于SpringBoot整合JWT的相關(guān)資料,需要的朋友可以參考下

1.JWT

JWT(JSON Web Token),為了在網(wǎng)絡(luò)應(yīng)用環(huán)境間傳遞聲明而執(zhí)行的一種基于JSON的開(kāi)放標(biāo)準(zhǔn)。將用戶信息加密到token中,服務(wù)器不保存任何用戶信息,服務(wù)器通過(guò)保存的密鑰驗(yàn)證token的正確性。

優(yōu)點(diǎn)

1.簡(jiǎn)介:可以通過(guò) URL POST 參數(shù)或者在 HTTP header 發(fā)送,因?yàn)閿?shù)據(jù)量小,傳輸速度也很快;

2.自包含:負(fù)載中可以包含用戶所需要的信息,避免了多次查詢(xún)數(shù)據(jù)庫(kù);

3.因?yàn)?Token 是以 JSON 加密的形式保存在客戶端的,所以 JWT 是跨語(yǔ)言的,原則上任何 web 形式都支持;

4.不需要再服務(wù)端保存會(huì)話信息,特別適用于分布式微服務(wù);

缺點(diǎn)

1.無(wú)法作廢已經(jīng)發(fā)布的令牌;

2.不易應(yīng)對(duì)數(shù)據(jù)過(guò)期;

2.JWT登錄執(zhí)行流程圖

3.為什么使用JWT?

  • 在傳統(tǒng)的用戶登錄認(rèn)證中,因?yàn)閔ttp是無(wú)狀態(tài)的,所以都是采用session+cokokie,用戶登錄成功,服務(wù)端會(huì)保存一個(gè)session,并給客戶端一個(gè)sessionId,客戶端會(huì)把sessionId保存在cookie中,每次請(qǐng)求都會(huì)攜帶sessionId。cookie+session模式是保存在內(nèi)存中,在分布式服務(wù)中會(huì)面臨session共享問(wèn)題,隨著用戶量得增加,開(kāi)銷(xiāo)就越來(lái)越大。而JWT不需要在服務(wù)端保存會(huì)話信息,特別適合分布式微服務(wù)。
  • 簡(jiǎn)潔:可以用過(guò)URL,POST參數(shù)或者在HTTP Header發(fā)送,因?yàn)閿?shù)據(jù)量小,傳輸速度也快
  • JWT支持跨語(yǔ)言
  • 自包含: 載荷中包含了所有用戶所需要的信息,避免了多次查詢(xún)數(shù)據(jù)庫(kù)。

4.JWT的組成

JWT由三部分構(gòu)成,類(lèi)似于如下:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJscyIsImV4cCI6MTYyNDU5Nzc5Nn0.4kwT1elZCb_k2D7AxbuFHM35VmBK4PcmLaqHhcHEq4_wVe8GVO8ODypGSKksTs-hraBopBCm2IC9EC2rO-GHng

第一部分為頭部(header),承載兩部分信息

聲明類(lèi)型(JWT)

聲明加密算法,默認(rèn)為HMAC SHA256

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

使用Base64加密后

第二部分為payload(載荷),存放有效信息的地方,這些有效信息分為三部分:

  • 標(biāo)準(zhǔn)中注冊(cè)的聲明
  • 公共的聲明
  • 私有的聲明

其中,標(biāo)準(zhǔn)中注冊(cè)的聲明 (建議但不強(qiáng)制使用)包括如下幾個(gè)部分 :

  • iss: jwt簽發(fā)者;
  • sub: jwt所面向的用戶;
  • aud: 接收jwt的一方;
  • exp: jwt的過(guò)期時(shí)間,這個(gè)過(guò)期時(shí)間必須要大于簽發(fā)時(shí)間;
  • nbf: 定義在什么時(shí)間之前,該jwt都是不可用的;
  • iat: jwt的簽發(fā)時(shí)間;
  • jwt的唯一身份標(biāo)識(shí),主要用來(lái)作為一次性token,從而回避重放攻擊

公共的聲明部分:

公共的聲明可以添加任何信息,一般添加用戶的相關(guān)信息或其他業(yè)務(wù)需要的必要信息,但不建議添加銘感信息,因?yàn)樵诳蛻舳丝山饷堋?/p>

私有的聲明部分:

私有的聲明是提供者和消費(fèi)者共同定義的聲明,不建議存放敏感信息,因?yàn)閎ase64是對(duì)稱(chēng)解密的,意味著該部分信息可以歸類(lèi)為明文信息。

第三部分為signature(簽證)

var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

//密鑰就是我們定義的secret,加密后得到簽證
var signature = HMACSHA256(encodedString, '密鑰');

5.SpringBoot整合JWT

引入依賴(lài)

  <!--JWT-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.4.0</version>
        </dependency>
          <!--StringUtils工具包-->
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <!--ConfigurationProperties出現(xiàn)異常-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

配置application.yml文件

server:
  port: 8888
spring:
  jwt:
    #過(guò)期時(shí)間
    expireTime: 1800000
    #加密密鑰
    secret: lsyyp5201314
    #token返回頭部
    header: LOGINTOKEN

JWT工具類(lèi)

package org.best.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.Date;

@ConfigurationProperties(prefix = "spring.jwt")
public class JWTUtils {

    public static String header;
    private static String secret;
    private static String expireTime;

    /**
     * 生成token
     * @param sub 用戶唯一信息
     * @return token
     */
    public  static   String createToken(String sub){
        return JWT
                .create()
                .withSubject(sub)
                .withExpiresAt(new Date(System.currentTimeMillis()+Long.parseLong(expireTime)))
                .sign(Algorithm.HMAC512(secret));
    }

    /**
     * 根據(jù)token獲取用戶信息
     * @param token
     * @return 用戶信息
     */
    public static String validateToken(String token){
        return JWT
                .require(Algorithm.HMAC512(secret))
                .build()
                .verify(token)
                .getSubject();
    }

    /**
     * 檢驗(yàn)Token是否需要刷新
     * @param token
     * @return
     */
    public static boolean refreshToken(String token) {
        Date expireDate = null;
        try {
            expireDate = JWT
                    .require(Algorithm.HMAC512(secret))
                    .build()
                    .verify(token)
                    .getExpiresAt();
        } catch (TokenExpiredException e) {
            return true;
        }
        return (expireDate.getTime()-System.currentTimeMillis())<0;
    }

    public void setHeader(String header) {
        this.header = header;
    }

    public String getSecret() {
        return secret;
    }

    public void setSecret(String secret) {
        this.secret = secret;
    }

    public String getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(String expireTime) {
        this.expireTime = expireTime;
    }
}

自定義攔截器

package org.best.config;

import org.apache.commons.lang.StringUtils;
import org.best.common.TokenIsNullException;
import org.best.common.TokenValidateException;
import org.best.util.JWTUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String logintoken = request.getHeader("LOGINTOKEN");
        //如果token為空
        if (StringUtils.isBlank(logintoken)){
            throw new TokenIsNullException("請(qǐng)登錄");
        }
        //校驗(yàn)Token
        String sub = JWTUtils.validateToken(logintoken);
        if (StringUtils.isBlank(sub)){
            throw new TokenValidateException("token校驗(yàn)失敗");
        }

        //更新token有效期(生產(chǎn)新token)
        if (JWTUtils.refreshToken(logintoken)){
            String token = JWTUtils.createToken(sub);
            response.setHeader(JWTUtils.header,token);
        }

        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

注冊(cè)攔截器

package org.best.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry
                .addInterceptor(new LoginInterceptor())
                .addPathPatterns("/find")
                .excludePathPatterns("/login");
    }
}

自定義異常

package org.best.common;

/**
 * Token校驗(yàn)異常
 */
public class TokenValidateException extends RuntimeException {
    public TokenValidateException() {
    }

    public TokenValidateException(String message) {
        super(message);
    }
}

package org.best.common;

/**
 * Token為空異常
 */
public class TokenIsNullException extends RuntimeException{
    public TokenIsNullException() {
    }

    public TokenIsNullException(String message) {
        super(message);
    }
}

自定義Controller

package org.best.controller;

import org.best.pojo.User;
import org.best.util.JWTUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
public class LoginController {
    @GetMapping("/login")
    public String login(User user, HttpServletResponse response){
        //這里就不做數(shù)據(jù)庫(kù)查詢(xún)了

        //根據(jù)用戶id生成token
        String token = JWTUtils.createToken(String.valueOf(user.getId()));
        //將token存入HTTP響應(yīng)頭中
        response.setHeader(JWTUtils.header,token);
        return user.toString();
    }

    @GetMapping("/find")
    public String find(){
        return "success";
    }
}

測(cè)試

登錄接口

我們來(lái)測(cè)試下find 接口 ,不帶token會(huì)出現(xiàn)啥情況

帶上token

總結(jié)

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

相關(guān)文章

  • mybatis-config.xml文件中的mappers標(biāo)簽使用

    mybatis-config.xml文件中的mappers標(biāo)簽使用

    在MyBatis配置中,<mapper>標(biāo)簽關(guān)鍵用于指定SQL?Mapper的XML文件路徑,主要有三種指定方式:resource、url和class,Resource方式從類(lèi)的根路徑開(kāi)始,適合放在項(xiàng)目?jī)?nèi)部保障移植性,URL方式指定絕對(duì)路徑,移植性差,適用于外部路徑
    2024-10-10
  • Java為何需要平衡方法調(diào)用與內(nèi)聯(lián)

    Java為何需要平衡方法調(diào)用與內(nèi)聯(lián)

    這篇文章主要介紹了Java為何需要平衡方法調(diào)用與內(nèi)聯(lián),幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2021-01-01
  • Java中的分布式鎖與同步鎖使用詳解

    Java中的分布式鎖與同步鎖使用詳解

    這篇文章主要介紹了Java中的分布式鎖與同步鎖使用詳解,在分布式系統(tǒng)中,由于存在多個(gè)節(jié)點(diǎn)并行執(zhí)行任務(wù),可能會(huì)出現(xiàn)競(jìng)爭(zhēng)條件和數(shù)據(jù)不一致的問(wèn)題,分布式鎖通過(guò)約束同一時(shí)刻只有一個(gè)節(jié)點(diǎn)能夠獲得鎖的方式,確保了對(duì)共享資源的獨(dú)占訪問(wèn),需要的朋友可以參考下
    2023-07-07
  • IntelliJ IDEA 2020 安裝和常用配置(推薦)

    IntelliJ IDEA 2020 安裝和常用配置(推薦)

    這篇文章主要介紹了IntelliJ IDEA 2020 安裝和常用配置(推薦),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • SpringBoot中REST API 接口傳參的實(shí)現(xiàn)

    SpringBoot中REST API 接口傳參的實(shí)現(xiàn)

    我們?cè)陂_(kāi)發(fā)?REST API?的過(guò)程中,經(jīng)常需要傳遞參數(shù),本文主要介紹了SpringBoot中REST API 接口傳參的實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • springsecurity實(shí)現(xiàn)登錄驗(yàn)證以及根據(jù)用戶身份跳轉(zhuǎn)不同頁(yè)面

    springsecurity實(shí)現(xiàn)登錄驗(yàn)證以及根據(jù)用戶身份跳轉(zhuǎn)不同頁(yè)面

    Spring?Security是一種基于Spring框架的安全技術(shù),用于實(shí)現(xiàn)身份驗(yàn)證和訪問(wèn)控制,本文介紹了如何使用Spring?Security,結(jié)合session和redis來(lái)存儲(chǔ)用戶信息,并通過(guò)編寫(xiě)特定的登錄處理類(lèi)和Web配置,實(shí)現(xiàn)用戶登錄和注銷(xiāo)功能
    2024-09-09
  • 淺談Java幾種文件讀取方式耗時(shí)

    淺談Java幾種文件讀取方式耗時(shí)

    本文主要介紹了淺談Java幾種文件讀取方式耗時(shí),主要介紹了4種,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Javaweb中使用Servlet編寫(xiě)簡(jiǎn)單的接口案例詳解

    Javaweb中使用Servlet編寫(xiě)簡(jiǎn)單的接口案例詳解

    文章介紹了如何使用Servlet編寫(xiě)一個(gè)簡(jiǎn)單的接口來(lái)校驗(yàn)用戶提交的密碼長(zhǎng)度是否在6到12位之間,代碼分為后端部分和前端部分,給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧
    2025-02-02
  • RabbitMQ 最常用的三大模式實(shí)例解析

    RabbitMQ 最常用的三大模式實(shí)例解析

    這篇文章主要介紹了RabbitMQ 最常用的三大模式實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java并發(fā)編程示例(六):等待線程執(zhí)行終止

    Java并發(fā)編程示例(六):等待線程執(zhí)行終止

    這篇文章主要介紹了Java并發(fā)編程示例(六):等待線程執(zhí)行終止,在本節(jié),示例程序演示等待初始化方法完成后,再去執(zhí)行其他任務(wù),需要的朋友可以參考下
    2014-12-12

最新評(píng)論

千阳县| 乐清市| 武隆县| 铁岭市| 岳普湖县| 商城县| 平顶山市| 盐亭县| 禹城市| 屯留县| 曲水县| 石景山区| 新巴尔虎右旗| 当涂县| 上饶县| 永修县| 林芝县| 漾濞| 廉江市| 石台县| 鄯善县| 黄浦区| 吴川市| 黎平县| 维西| 辉县市| 阿克苏市| 绥江县| 大港区| 乌鲁木齐县| 柳河县| 建平县| 连州市| 黄浦区| 枞阳县| 林口县| 宁化县| 恭城| 霍邱县| 苏州市| 句容市|