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

Springboot3+Vue3實(shí)現(xiàn)JWT登錄鑒權(quán)功能

 更新時(shí)間:2025年03月27日 08:50:00   作者:師大無(wú)語(yǔ)  
JWT用于在網(wǎng)絡(luò)應(yīng)用間安全的傳遞消息,它以緊湊且自包含的方式,通過JSON對(duì)象在各方之間傳遞經(jīng)過驗(yàn)證的信息,這篇文章主要介紹了Springboot3+Vue3實(shí)現(xiàn)JWT登錄鑒權(quán)功能,需要的朋友可以參考下

做鑒權(quán)原因:

管理系統(tǒng)的數(shù)據(jù)是敏感的,隱私的,每個(gè)角色的權(quán)限是不同的,必須在數(shù)據(jù)的增刪改查操作時(shí)候?qū)υL問的用戶進(jìn)行權(quán)限驗(yàn)證

JWT(Json Web Token)

用于在網(wǎng)絡(luò)應(yīng)用間安全的傳遞消息。它以緊湊且自包含的方式,通過JSON對(duì)象在各方之間傳遞經(jīng)過驗(yàn)證的信息。JWT通常由三部分組成,用點(diǎn)號(hào)(.)分隔:header.payload.signature

集成JWT(在pom中引入依賴)

<!--java-JWT坐標(biāo) -->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>4.4.0</version>
        </dependency>

生成token

/**
     * 生成 JWT 令牌
     */
    public static String createToken(String data,String sign) {
        return JWT.create().withAudience(data)//將userid-role保存到token里面作為載荷
                .withExpiresAt(DateUtil.offsetDay(new Date(),1))//1天后token過期
                .sign(Algorithm.HMAC256(sign));//以password作為token的密鑰,使用HMAC256算法加密
    }

在***Service中創(chuàng)建token返回前端

String token = TokenUtil.createToken(dbUser.getId()+"-"+"管理員",dbUser.getPassword());<br data-filtered="filtered">dbUser.setToken(token);

Token格式

"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIxLeeuoeeQhuWRmCIsImV4cCI6MTc0MjkyMTk5Mn0.PH2OJMzhqZFuJz-aW5nWfE5wZk9fbM-tgxPql1_NNVI"

JWT攔截器對(duì)所有訪問的接口進(jìn)行驗(yàn)證

通過webConfig做一層攔截器攔截所有的接口

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor())
                .addPathPatterns("/**")//校驗(yàn)規(guī)則所有接口
                .excludePathPatterns("/login","/register");//排除登錄和注冊(cè)接口
    }
    @Bean
    public JWTInterceptor jwtInterceptor(){
        return new JWTInterceptor();
    }
}

JWT攔截器

/**
 * JWT攔截器
 * 做攔截器的實(shí)現(xiàn)
 * 對(duì)Token進(jìn)行攔截并進(jìn)一步解析Token、驗(yàn)證Token,看看Token是否是合法的
 */
@Component
public class JWTInterceptor implements HandlerInterceptor {
    @Resource
    private UserService userService;
    @Resource
    private ZuKeService zuKeService;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.從請(qǐng)求頭拿到Token
        String token=request.getHeader("token");
        if (StrUtil.isEmpty(token)){
            //如果沒拿到,從參數(shù)中再拿一次
            token=request.getParameter("token");
        }
        //2.認(rèn)證Token
        if (StrUtil.isBlank(token)){
            throw new CustomException("401","您無(wú)權(quán)操作");
        }
        Account account=null;
        try {
            //拿到Token載荷數(shù)據(jù)
            String audience = JWT.decode(token).getAudience().get(0);
            String[] split=audience.split("-");
            String userId=split[0];
            String role=split[1];
            //柑橘Token解析出來(lái)的userId去對(duì)應(yīng)的表查詢信息
            if ("管理員".equals(role)){
                account=userService.selectById(userId);
            } else if ("租客".equals(role)) {
                account=zuKeService.selectById(userId);
            }
        } catch (Exception e) {
            throw new CustomException("401","您無(wú)權(quán)操作");
        }
        if (account==null){
            throw new CustomException("401","您無(wú)權(quán)操作");
        }
        try {
            //用戶加簽 驗(yàn)證簽名
            JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(account.getPassword())).build();
            jwtVerifier.verify(token);
        } catch (Exception e) {
            throw new CustomException("401","您無(wú)權(quán)操作");
        }
        return true;
    }
}

出現(xiàn)401錯(cuò)誤,無(wú)權(quán)訪問數(shù)據(jù)怎么辦

 在Vue的request.js的攔截器里面添加統(tǒng)一的請(qǐng)求頭Token

 request.js的代碼

import axios from "axios";
import {ElMessage} from "element-plus";
const request = axios.create({
    baseURL:'http://localhost:8080',//后端統(tǒng)一的請(qǐng)求地址
    timeout:30000 //后臺(tái)接口時(shí)間
})
//request 攔截器
//可以自請(qǐng)求發(fā)送前對(duì)請(qǐng)求做一些處理
request.interceptors.request.use(config =>{
    //統(tǒng)一的數(shù)據(jù)傳輸格式為json,統(tǒng)一的編碼utf-8
    config.headers['Content-Type']='application/json;charset=utf-8';
    //let user=JSON.parse(localStorage.getItem('pro1-user') || '{}');
    //config.headers['token']=user.token;
    // ? 安全獲取 user(兼容 null 和異常情況)
    let user = {};
    try {
        const userStr = localStorage.getItem('pro1-user');
        user = userStr ? JSON.parse(userStr) : {};
    } catch (e) {
        console.error('解析 pro1-user 失敗:', e);
    }
    // 僅當(dāng) token 存在時(shí)才添加到 headers
    if (user.token) {
        config.headers['token'] = user.token;
    } else {
        console.warn('Token 不存在,請(qǐng)求可能被后端拒絕');
        // 可選:跳轉(zhuǎn)到登錄頁(yè)
        // window.location.href = '/login';
    }
    return config;
},error=>{
    return Promise.reject(error)
});
//response攔截器
//可以在接口響應(yīng)后統(tǒng)一處理結(jié)果
request.interceptors.response.use(
    response =>{
        let res=response.data;
        //兼容服務(wù)端返回的字符串?dāng)?shù)據(jù)
        if(typeof  res === 'string'){
            //如果是string,轉(zhuǎn)成json
            res = res ? JSON.parse(res) : res
        }
        if (res.code === '401'){
            ElMessage.error(res.msg);
            router.push('/login')
        }else {
            return res;
        }
    },
    error =>{
        //后端返回?cái)?shù)據(jù)判斷
        if (error.response.status === 404){
            ElMessage.error('未找到請(qǐng)求接口')
        }else if (error.response.status === 500){
            ElMessage.error('系統(tǒng)異常,請(qǐng)查看后端控制臺(tái)報(bào)錯(cuò)')
        }else{
            console.error(error.message)
        }
        return Promise.reject(error)
    }
)
export default request

獲取當(dāng)前登錄用戶信息

@Component
public class TokenUtil {
    @Resource
    UserService userService;
    @Resource
    ZuKeService zuKeService;
    static UserService stasticUserService;
    static ZuKeService stasticZuKeService;
    /**
     * 生成 JWT 令牌
     */
    public static String createToken(String data,String sign) {
        return JWT.create().withAudience(data)//將userid-role保存到token里面作為載荷
                .withExpiresAt(DateUtil.offsetDay(new Date(),1))//1天后token過期
                .sign(Algorithm.HMAC256(sign));//以password作為token的密鑰,使用HMAC256算法加密
    }
    /**
     * 獲取當(dāng)前登錄用戶信息
     * @return
     */
    public static Account getCurrentUser(){
        Account account=null;
        HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
        String token=request.getHeader("token");
        if (StrUtil.isEmpty(token)){
            //如果沒拿到,從參數(shù)中再拿一次
            token=request.getParameter("token");
        }
        //拿到Token載荷數(shù)據(jù)
        String audience = JWT.decode(token).getAudience().get(0);
        String[] split=audience.split("-");
        String userId=split[0];
        String role=split[1];
        if ("管理員".equals(role)){
            return stasticUserService.selectById(userId);
        }else if ("租客".equals(role)){
            return stasticZuKeService.selectById(userId);
        }
        return null;
    }
}

在service方法里面獲取當(dāng)前登錄用戶的信息

Account currentUser=TokenUtil.getCurrentUser();

到此這篇關(guān)于Springboot3+Vue3實(shí)現(xiàn)JWT登錄鑒權(quán)的文章就介紹到這了,更多相關(guān)Springboot3+Vue3實(shí)現(xiàn)JWT登錄鑒權(quán)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入了解JVM字節(jié)碼增強(qiáng)技術(shù)

    深入了解JVM字節(jié)碼增強(qiáng)技術(shù)

    這篇文章主要介紹了深入了解JVM字節(jié)碼增強(qiáng)技術(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • SpringBoot部署到騰訊云的實(shí)現(xiàn)示例

    SpringBoot部署到騰訊云的實(shí)現(xiàn)示例

    記錄一下自己第一次部署springboot項(xiàng)目,本文主要介紹了SpringBoot部署到騰訊云的實(shí)現(xiàn)示例,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • java的各種集合為什么不安全(List、Set、Map)以及代替方案

    java的各種集合為什么不安全(List、Set、Map)以及代替方案

    這篇文章主要介紹了java的各種集合為什么不安全(List、Set、Map)以及代替方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • java微信開發(fā)API第一步 服務(wù)器接入

    java微信開發(fā)API第一步 服務(wù)器接入

    這篇文章主要為大家分享了java微信開發(fā)API的第一步操作服務(wù)器接入,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Spring?Boot?中starter的原理詳析

    Spring?Boot?中starter的原理詳析

    這篇文章主要介紹了Spring?Boot?中starter原理詳析,文章圍繞主題展開springboot的插件機(jī)制和starter原理相關(guān)資料,需要的小伙伴可以參考一下
    2022-06-06
  • Java GZIP壓縮與解壓縮代碼實(shí)例

    Java GZIP壓縮與解壓縮代碼實(shí)例

    這篇文章主要介紹了Java GZIP壓縮與解壓縮代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • Java實(shí)現(xiàn)的生成二維碼統(tǒng)計(jì)掃描次數(shù)并轉(zhuǎn)發(fā)到某個(gè)地址功能詳解

    Java實(shí)現(xiàn)的生成二維碼統(tǒng)計(jì)掃描次數(shù)并轉(zhuǎn)發(fā)到某個(gè)地址功能詳解

    這篇文章主要介紹了Java實(shí)現(xiàn)的生成二維碼統(tǒng)計(jì)掃描次數(shù)并轉(zhuǎn)發(fā)到某個(gè)地址功能,可實(shí)現(xiàn)生成帶統(tǒng)計(jì)功能的二維碼,涉及java二維碼的生成、參數(shù)傳遞、解析等相關(guān)操作技巧,需要的朋友可以參考下
    2018-07-07
  • spring?MVC實(shí)現(xiàn)簡(jiǎn)單登錄功能

    spring?MVC實(shí)現(xiàn)簡(jiǎn)單登錄功能

    這篇文章主要為大家詳細(xì)介紹了spring?MVC實(shí)現(xiàn)簡(jiǎn)單登錄功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-09-09
  • SpringBoot讀取Resource下文件的4種方法

    SpringBoot讀取Resource下文件的4種方法

    這篇文章主要介紹了SpringBoot讀取Resource下文件的4種方法小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 修改request請(qǐng)求的header請(qǐng)求頭實(shí)現(xiàn)方式

    修改request請(qǐng)求的header請(qǐng)求頭實(shí)現(xiàn)方式

    本文介紹了在Spring Cloud Gateway中修改HTTP請(qǐng)求頭的方法,包括直接操作ServerHttpRequest對(duì)象和創(chuàng)建自定義Request請(qǐng)求包裝類兩種方式,此方法可用于替換Authorization請(qǐng)求頭中的token
    2026-04-04

最新評(píng)論

海门市| 威宁| 平原县| 体育| 宝山区| 安龙县| 清新县| 安阳县| 长岛县| 孟连| 井陉县| 花垣县| 武夷山市| 扎囊县| 塔城市| 嘉定区| 西丰县| 遂平县| 通辽市| 永丰县| 泸定县| 清河县| 仙游县| 沁阳市| 东至县| 广东省| 正阳县| 鄂伦春自治旗| 龙山县| 乡城县| 惠水县| 鲁甸县| 金川县| 个旧市| 英山县| 玉龙| 上思县| 开平市| 永清县| 大兴区| 渝中区|