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

SpringBoot+vue實現(xiàn)token認(rèn)證登錄過程

 更新時間:2026年01月07日 09:06:12   作者:小七.布靈  
本文介紹了如何在SpringBoot和Vue.js中實現(xiàn)基于JWT的token認(rèn)證登錄機制,包括后端生成和驗證JWT,前端發(fā)送請求攜帶Token以及使用路由守衛(wèi)保護(hù)認(rèn)證路由

在Spring Boot和Vue.js中實現(xiàn)token認(rèn)證登錄是一種常見的前后端分離的認(rèn)證機制。

以下是實現(xiàn)這一機制的基本步驟:

后端(Spring Boot)

1. 創(chuàng)建用戶實體和數(shù)據(jù)庫表

首先,你需要定義一個用戶實體,比如User,并為其創(chuàng)建相應(yīng)的數(shù)據(jù)庫表。

@TableField(exist = false)
private String token; // 表示我們數(shù)據(jù)庫沒有這個字段,但是在前端我們需要返回這個字段

2. 用戶注冊和登錄接口

在Spring Boot應(yīng)用中創(chuàng)建用于注冊和登錄的REST API。

@Override
public User login(UserPasswordDTO userPasswordDTO) {
    User one = getUserInfo(userPasswordDTO);
    if (one != null) {
        BeanUtil.copyProperties(one, userPasswordDTO, true);
        // 設(shè)置token
        String token = TokenUtils.genToken(one.getId().toString(), one.getPassword());
        one.setToken(token);
        return one;
    }else{
        return null;
    }
}

private User getUserInfo(UserPasswordDTO userPasswordDTO){
    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("username", userPasswordDTO.getUsername());
    queryWrapper.eq("password", SecureUtil.md5(userPasswordDTO.getPassword()));
    List<User> one =  userMapper.selectList(queryWrapper);
    if (one.size()==0){
        return null;
    }
    return one.get(0);
}

3. JWT Token生成

用戶登錄成功后,生成一個JWT(JSON Web Token),并將其發(fā)送回客戶端。

首先在pom.xml文件中導(dǎo)入jwt包:

<!-- JWT -->
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>java-jwt</artifactId>
    <version>3.10.3</version>
</dependency>

在config包中新建TokenUtils類:

package com.lyk.xuelang.config;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.lyk.xuelang.entity.User;
import com.lyk.xuelang.mapper.UserMapper;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

@Component
public class TokenUtils {
    private static UserMapper staticUserMapper;

    @Resource
    private UserMapper userMapper;

    @PostConstruct
    public void setUserService() {
        staticUserMapper = userMapper;
    }

    /**
     * 生成token
     *
     * @return
     */
    public static String genToken(String userId, String sign) {
        return JWT.create().withAudience(userId) // 將 user id 保存到 token 里面,作為載荷
                .withExpiresAt(DateUtil.offsetHour(new Date(), 2)) // 2小時后token過期
                .sign(Algorithm.HMAC256(sign)); // 以 password 作為 token 的密鑰
    }

    /**
     * 獲取當(dāng)前登錄的用戶信息
     *
     * @return user對象
     */
    public static User getCurrentUser() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String token = request.getHeader("token");
            if (StrUtil.isNotBlank(token)) {
                String userId = JWT.decode(token).getAudience().get(0);
                return staticUserMapper.selectById(Integer.valueOf(userId));
            }
        } catch (Exception e) {
            return null;
        }
        return null;
    }
}

4. JWT Token驗證

在config包下新建interceptor包,然后新建JwtInterceptor類:

package com.lyk.xuelang.config.interceptor;

import cn.hutool.core.util.StrUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.lyk.xuelang.common.Constants;
import com.lyk.xuelang.entity.User;
import com.lyk.xuelang.exception.ServiceException;
import com.lyk.xuelang.service.IUserService;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

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

@Component
public class JwtInterceptor implements HandlerInterceptor {
    @Resource
    private IUserService userService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getHeader("token");
        if(!(handler instanceof HandlerMethod)){
            return true;
        }

        // 執(zhí)行認(rèn)證
        if (StrUtil.isBlank(token)) {
            throw new ServiceException(Constants.CODE_401, "無token驗證失敗");
        }
        // 獲取 token 中的 userId
        String userId;
        try {
            userId = JWT.decode(token).getAudience().get(0);
        } catch (JWTDecodeException j) {
            String errMsg = "token驗證失敗,請重新登錄";
            throw new ServiceException(Constants.CODE_401, errMsg);
        }
        // 根據(jù)token中的userid查詢數(shù)據(jù)庫
        User user = userService.getById(userId);
        if (user == null) {
            throw new ServiceException(Constants.CODE_401, "用戶不存在,請重新登錄");
        }
        // 用戶密碼加簽驗證 token
        JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build();
        try {
            jwtVerifier.verify(token); // 驗證token
        } catch (JWTVerificationException e) {
            throw new ServiceException(Constants.CODE_401, "token驗證失敗,請重新登錄");
        }
        return true;
    }
}

添加自定義攔截器

在config包下新建InterceptorConfig類:

package com.lyk.xuelang.config;

import com.lyk.xuelang.config.interceptor.JwtInterceptor;
import org.springframework.context.annotation.Bean;
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 InterceptorConfig implements WebMvcConfigurer {

        @Override
        // 加自定義攔截器JwtInterceptor,設(shè)置攔截規(guī)則
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(jwtInterceptorl())
                    .addPathPatterns("/**") //攔截所有請求,通過判斷token是否合法來決定是否登錄
                    .excludePathPatterns("/login","/role/page","/**/export","/**/import");//排除這些接口,也就是說,這些接口可以放行
        }
       @Bean
       public JwtInterceptor jwtInterceptorl(){
            return new JwtInterceptor();
        }
}

前端(Vue.js)

1. 用戶界面

創(chuàng)建登錄表單,允許用戶輸入用戶名和密碼。

<div class="login-container">
  <el-card class="login-card">
    <h2 class="login-title">倉庫管理系統(tǒng)</h2>
    <el-form :model="loginForm" :rules="rules" ref="loginForm" label-width="20">
      <el-form-item label="用戶名" prop="username">
        <el-input v-model="loginForm.username" placeholder="請輸入用戶名"></el-input>
      </el-form-item>
      <el-form-item label="密碼" prop="password">
        <el-input type="password" v-model="loginForm.password" placeholder="請輸入密碼"></el-input>
      </el-form-item>
      <el-form-item style="margin: 10px 0;text-align: right;" label="溫馨提示:忘記密碼?聯(lián)系管理員!">
        <el-button type="primary" autocomplete="off" @click="submitForm">登錄</el-button>
      </el-form-item>
    </el-form>
  </el-card>
</div>

2. 發(fā)送登錄請求

用戶提交表單后,前端發(fā)送登錄請求到后端的登錄接口。

login.js代碼如下:

import request from '@/utils/request'

// 用戶登錄
export function login (user) {
  return request({
    url: '/login',
    method: 'post',
    data: user
  })
}

Home.vue頁面代碼如下:

<script>
import { login } from '@/api/login'

export default {
  data () {
    return {
      loginForm: {
        username: '',
        password: ''
      },
      rules: {
        username: [
          { required: true, message: '請輸入用戶名!', trigger: 'blur' }
        ],
        password: [
          { required: true, message: '請輸入密碼!', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    submitForm () {
      this.$refs.loginForm.validate(async (valid) => {
        if (valid) {
          // 在這里添加你的登錄邏輯
          const res = await login(this.loginForm)
          if (res.code === 200) {
            this.$message.success('登錄成功')
            localStorage.setItem('user', JSON.stringify(res.data)) // 存儲用戶信息到瀏覽器
            localStorage.setItem('token', JSON.stringify(res.data.token))
            this.$router.push('/main')
          } else {
            this.$message.error(res.msg)
          }
        } else {
          this.$message.error('賬號密碼錯誤,請重新輸入!')
          return false
        }
      })
    }
  }
}
</script>

3. 接收并存儲Token

登錄成功后,前端接收J(rèn)WT Token,并將其存儲在本地存儲(localStorage)或Vuex狀態(tài)管理中。

// 在這里添加你的登錄邏輯
const res = await login(this.loginForm)
if (res.code === 200) {
  this.$message.success('登錄成功')
  localStorage.setItem('user', JSON.stringify(res.data)) // 存儲用戶信息到瀏覽器
  localStorage.setItem('token', JSON.stringify(res.data.token))
  this.$router.push('/main')
}

4. 發(fā)送請求時攜帶Token

在發(fā)送需要認(rèn)證的請求時,前端需要在請求頭中攜帶JWT Token。

// 添加請求攔截器,一下內(nèi)容是axios的攔截器,可以不用寫
request.interceptors.request.use(config => {
  config.headers['Content-Type'] = 'application/json;charset=utf-8'
  const user = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : null
  if (user) {
    config.headers.token = user.token
  }

  return config
}, error => {
  return Promise.reject(error)
})

5. 路由守衛(wèi)

使用Vue Router的路由守衛(wèi)來保護(hù)需要認(rèn)證的路由。

{ path: '/dashboard', 
    component: Dashboard,
    meta: 
       {requiresAuth: true} 
} // 標(biāo)記需要驗證的路由
router.beforeEach((to, from, next) => {
  const auth = require('@/router/auth').default // 引入認(rèn)證守衛(wèi)
  auth.redirectIfNotAuthenticated(to, from, next)
})

auth.js代碼如下:

export default {
  isAuthenticated () {
    // 這里應(yīng)該根據(jù)你的應(yīng)用邏輯來檢查用戶是否登錄
    // 例如,檢查本地存儲(localStorage)中是否有token
    return localStorage.getItem('token') !== null
  },

  redirectIfNotAuthenticated (to, from, next) {
    if (!this.isAuthenticated()) {
      to.path !== '/login' && to.matched.some(record => record.meta.requiresAuth) ? next({ path: '/login' }) : next()
    } else {
      next()
    }
  }
}

注意事項

  • 安全性:確保使用HTTPS來傳輸JWT Token。
  • Token存儲:考慮使用HttpOnly的Cookie來存儲Token,以避免XSS攻擊。
  • Token過期:JWT Token應(yīng)該有過期時間,并且后端需要處理Token的刷新。

這只是一個簡單的示例,實際應(yīng)用中可能需要更復(fù)雜的邏輯,比如密碼加密、Token刷新機制、用戶角色和權(quán)限管理等。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • IDEA 自動生成 JPA 實體類的圖文教程

    IDEA 自動生成 JPA 實體類的圖文教程

    這篇文章主要介紹了IDEA 自動生成 JPA 實體類的圖文教程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java ThreadGroup的作用及方法詳解

    java ThreadGroup的作用及方法詳解

    這篇文章主要介紹了java ThreadGroup的作用及方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • SpringBoot+Mybatis-plus實現(xiàn)分頁查詢的示例代碼

    SpringBoot+Mybatis-plus實現(xiàn)分頁查詢的示例代碼

    本文主要介紹了SpringBoot+Mybatis-plus實現(xiàn)分頁查詢的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • 解決JSON.toJSONString首字母大小寫的問題

    解決JSON.toJSONString首字母大小寫的問題

    這篇文章主要介紹了解決JSON.toJSONString首字母大小寫的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Springboot項目出現(xiàn)java.lang.ArrayStoreException的異常分析

    Springboot項目出現(xiàn)java.lang.ArrayStoreException的異常分析

    這篇文章介紹了Springboot項目出現(xiàn)java.lang.ArrayStoreException的異常分析,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-12-12
  • Springboot配置Swagger的實現(xiàn)示例

    Springboot配置Swagger的實現(xiàn)示例

    Swagger?是一種提高?API?開發(fā)和維護(hù)效率的工具,它使開發(fā)者能夠更輕松地構(gòu)建、測試和文檔化?API,本文主要介紹了Springboot配置Swagger的實現(xiàn)示例,感興趣的可以了解一下
    2023-10-10
  • 基于Java代碼實現(xiàn)數(shù)字在數(shù)組中出現(xiàn)次數(shù)超過一半

    基于Java代碼實現(xiàn)數(shù)字在數(shù)組中出現(xiàn)次數(shù)超過一半

    這篇文章主要介紹了基于Java代碼實現(xiàn)數(shù)字在數(shù)組中出現(xiàn)次數(shù)超過一半的相關(guān)資料,需要的朋友可以參考下
    2016-02-02
  • Java面試題沖刺第二十五天--并發(fā)編程3

    Java面試題沖刺第二十五天--并發(fā)編程3

    這篇文章主要為大家分享了最有價值的三道關(guān)于并發(fā)編程的面試題,涵蓋內(nèi)容全面,包括數(shù)據(jù)結(jié)構(gòu)和算法相關(guān)的題目、經(jīng)典面試編程題等,感興趣的小伙伴們可以參考一下
    2021-08-08
  • 解決Java編譯時錯誤:A JNI error has occurred,please check your installation and try again

    解決Java編譯時錯誤:A JNI error has occurred,ple

    這篇文章主要介紹了解決Java編譯時錯誤:A JNI error has occurred,please check your installation and try again,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • SpringBoot 整合線程池的示例詳解

    SpringBoot 整合線程池的示例詳解

    線程池是一種利用池化技術(shù)思想來實現(xiàn)的線程管理技術(shù),主要是為了復(fù)用線程、便利地管理線程和任務(wù)、并將線程的創(chuàng)建和任務(wù)的執(zhí)行解耦開來,這篇文章主要介紹了SpringBoot 整合線程池的示例詳解,需要的朋友可以參考下
    2024-08-08

最新評論

婺源县| 辽源市| 民勤县| 繁昌县| 莒南县| 余姚市| 鞍山市| 通渭县| 信宜市| 循化| 苍梧县| 南涧| 哈尔滨市| 桐柏县| 塔河县| 新野县| 桂林市| 信宜市| 清流县| 蓝田县| 都江堰市| 南丰县| 合江县| 额济纳旗| 纳雍县| 响水县| 商都县| 常宁市| 时尚| 沈丘县| 博白县| 梧州市| 金乡县| 博客| 临海市| 牙克石市| 瓮安县| 太谷县| 蒙城县| 喜德县| 珠海市|