<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Springboot3+Vue3實現JWT登錄鑒權

      做鑒權原因:

      管理系統的數據是敏感的,隱私的,每個角色的權限是不同的,必須在數據的增刪改查操作時候對訪問的用戶進行權限驗證

      JWT(Json Web Token)

      用于在網絡應用間安全的傳遞消息。它以緊湊且自包含的方式,通過JSON對象在各方之間傳遞經過驗證的信息。JWT通常由三部分組成,用點號(.)分隔:header.payload.signature

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

      <!--java-JWT坐標 -->
              <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中創建token返回前端

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

       

      Token格式

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

      JWT攔截器對所有訪問的接口進行驗證

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

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

      JWT攔截器

      /**
       * JWT攔截器
       * 做攔截器的實現
       * 對Token進行攔截并進一步解析Token、驗證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.從請求頭拿到Token
              String token=request.getHeader("token");
              if (StrUtil.isEmpty(token)){
                  //如果沒拿到,從參數中再拿一次
                  token=request.getParameter("token");
              }
              //2.認證Token
              if (StrUtil.isBlank(token)){
                  throw new CustomException("401","您無權操作");
              }
              Account account=null;
              try {
                  //拿到Token載荷數據
                  String audience = JWT.decode(token).getAudience().get(0);
                  String[] split=audience.split("-");
                  String userId=split[0];
                  String role=split[1];
                  //柑橘Token解析出來的userId去對應的表查詢信息
                  if ("管理員".equals(role)){
                      account=userService.selectById(userId);
                  } else if ("租客".equals(role)) {
                      account=zuKeService.selectById(userId);
                  }
              } catch (Exception e) {
                  throw new CustomException("401","您無權操作");
              }
              if (account==null){
                  throw new CustomException("401","您無權操作");
              }
              try {
                  //用戶加簽 驗證簽名
                  JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(account.getPassword())).build();
                  jwtVerifier.verify(token);
              } catch (Exception e) {
                  throw new CustomException("401","您無權操作");
              }
              return true;
          }
      }

      出現401錯誤,無權訪問數據怎么辦

       在Vue的request.js的攔截器里面添加統一的請求頭Token

       request.js的代碼

      import axios from "axios";
      import {ElMessage} from "element-plus";
      
      const request = axios.create({
          baseURL:'http://localhost:8080',//后端統一的請求地址
          timeout:30000 //后臺接口時間
      })
      //request 攔截器
      //可以自請求發送前對請求做一些處理
      request.interceptors.request.use(config =>{
          //統一的數據傳輸格式為json,統一的編碼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);
          }
      
          // 僅當 token 存在時才添加到 headers
          if (user.token) {
              config.headers['token'] = user.token;
          } else {
              console.warn('Token 不存在,請求可能被后端拒絕');
              // 可選:跳轉到登錄頁
              // window.location.href = '/login';
          }
          return config;
      },error=>{
          return Promise.reject(error)
      });
      //response攔截器
      //可以在接口響應后統一處理結果
      request.interceptors.response.use(
          response =>{
              let res=response.data;
              //兼容服務端返回的字符串數據
              if(typeof  res === 'string'){
                  //如果是string,轉成json
                  res = res ? JSON.parse(res) : res
              }
              if (res.code === '401'){
                  ElMessage.error(res.msg);
                  router.push('/login')
              }else {
                  return res;
              }
      
          },
          error =>{
              //后端返回數據判斷
              if (error.response.status === 404){
                  ElMessage.error('未找到請求接口')
              }else if (error.response.status === 500){
                  ElMessage.error('系統異常,請查看后端控制臺報錯')
              }else{
                  console.error(error.message)
              }
              return Promise.reject(error)
          }
      )
      export default request

      獲取當前登錄用戶信息

      @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算法加密
          }
      
          /**
           * 獲取當前登錄用戶信息
           * @return
           */
          public static Account getCurrentUser(){
              Account account=null;
              HttpServletRequest request=((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
              String token=request.getHeader("token");
              if (StrUtil.isEmpty(token)){
                  //如果沒拿到,從參數中再拿一次
                  token=request.getParameter("token");
              }
              //拿到Token載荷數據
              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方法里面獲取當前登錄用戶的信息

       Account currentUser=TokenUtil.getCurrentUser();
      posted @ 2025-03-27 01:07  師大無語  閱讀(598)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲中文字幕无码久久2020| 国产精品黑色丝袜在线观看| 精品国产三级a∨在线欧美| 波多野结av在线无码中文免费| 蜜臀视频在线观看一区二区| 天天影视色香欲综合久久| 亚洲男人AV天堂午夜在| 少妇被躁爽到高潮无码文| 国内精品久久毛片一区二区| 2020国产欧洲精品网站| 亚洲aⅴ天堂av天堂无码麻豆| 国产高清在线男人的天堂| 999精品全免费观看视频| 国产精品中文字幕自拍| 狠狠噜天天噜日日噜视频麻豆| 疯狂的欧美乱大交| 国内揄拍国内精品人妻久久| 亚洲色拍拍噜噜噜最新网站| 丁香五香天堂网| 又大又粗欧美成人网站| 99精品伊人久久久大香线蕉| 深夜av在线免费观看| 亚洲av专区一区| 国产亚洲999精品AA片在线爽| 双城市| 荃湾区| 潘金莲高清dvd碟片| 午夜大片免费男女爽爽影院| 乱老年女人伦免费视频| 亚洲性日韩一区二区三区| 成人3D动漫一区二区三区| 巴中市| 国产又黄又爽又不遮挡视频| 国产亚洲精品俞拍视频| 国产精品视频中文字幕| 无码国产精品一区二区av| 国内精品久久人妻无码网站| 国产精品无码无需播放器| 久久91精品牛牛| 久久精品国产亚洲AV瑜伽| 国产成人无码免费视频在线|