springBoot+Vue 的token登录验证的使用

springBoot+Vue 的token登录验证的使用

前端Vue

登录页请求代码:

// 登入
function login(){
if(user.userCode === "" || user.userPassword === ""){
flag.value = true
msg.value = "账号或者密码不能为空"
}else{
// md加密 (我这里前后端都对密码进行了md5加密,你们测试这里可以不需要,如果需要就要下载md的包)
user.userPassword = md5(user.userPassword)
let userString = JSON.stringify(user)
// 登入请求
proxy.$axios.post(`${proxy.PATH}/login/${userString}`).then(
response=>{
const data = response.data;
if(data.is_login){//登录成功
localStorage.setItem("token",data.token) //保存token
localStorage.setItem("userCode",data.userCode)
router.push({//登录成功后进行跳转
name:"manage"
})
}else{
msg.value = data.msg
flag.value = true
}
},
error=>{
console.log('请求失败了',error.message)
}
)
}
}

每次向后端发送请求的时候都带上这个token,这个可以设置到mian.js

// 每次请求前 有token就带上
axios.interceptors.request.use( config => {
const token = localStorage.getItem("token");
if(token !== null && token !== ""){
config.headers.token = token;
}
return config
})

为了防止没有token或者token不正确的也不能进入需要登录的页面,还设置了前置路由守卫

const PATH = "http://localhost:8888/blog"
//全局前置路由守卫,权限检测,初始化时也会被调用
router.beforeEach((to,from,next)=>{
const path = to.path
//判断请求路径中是否带有这个地址
if(path.indexOf("/blog/manage/") != -1 ){
const token = localStorage.getItem("token");
if(token !== null && token !== ""){//是否带有token
axios.get(`${PATH}/token/${token}`).then(//去后端判断这个token是否正确
response=>{
if(response.data){//正确就放行
next();
}else{//错误就跳到登录页
next("/blog/login")
}
},
error=>{
console.log('请求失败了',error.message)
})
}else{
next("/blog/login")
}
}else{
next()
}
})

后端springBoot

需要导入上传token的设密依赖jwt

<!-- token jwt加密 解密 -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>

编写生成token和判断token是否正确的的工具类

package com.mhy.blog.utils;
import com.mhy.blog.pojo.User;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class TokenUtils {
// 签名过期时间 10个小时
private static final long EXPIRE_TIME = 10*60*60*1000;
// 签名秘钥 可以自己设定
private static final String PRIVATE_KEY = "shuisanya";
// 生成token
public static String sign(User user){
String token = "";
Map<String,Object> header = new HashMap<>();
header.put("typ","JWT");
header.put("alg","HS256");
Map<String ,Object> claims = new HashMap<>();
// 自定义有效荷载部分
claims.put("account",user.getUserCode());
token = Jwts.builder()
// 发证人
.setIssuer("auth")
// jwt头
.setHeader(header)
// 有效负荷
.setClaims(claims)
// 设定签订时间
.setIssuedAt(new Date())
// 设定过期时间
.setExpiration(new Date(System.currentTimeMillis() + EXPIRE_TIME))
// 使用SignatureAlgorithm.HS256算法,加密,秘钥是:PRIVATE_KEY
.signWith(SignatureAlgorithm.HS256,PRIVATE_KEY)
.compact();
return token;
}
// 生成token是否正确
public static boolean verify(String token){
try {
Jwts.parser()
.setSigningKey(PRIVATE_KEY)
.parseClaimsJws(token).getBody();
return true;
}catch (Exception e){
return false;
}
}
}

配置拦截器,需要拦截哪些请求需要token

options请求的官方定义:OPTIONS方法是用于请求获得由Request-URI标识的资源在请求/响应的通信过程中可以使用的功能选项。通过这个方法,客户端可以在采取具体资源请求之前,决定对该资源采取何种必要措施,或者了解服务器的性能。
其实就是:在发生正式的请求之前,先进行一次预检请求。看服务端返回一些信息,浏览器拿到之后,看后台是否允许进行访问。

package com.mhy.blog.interceptor;
import com.mhy.blog.utils.TokenUtils;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//这里一定不要忘了设置OPTIONS这个跨域请求,第一个请求一般不带token,然后会发起第二次请求带token
if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){
// System.out.println("跨域的第一次 OPTIONS 放行");
return true;
}
// System.out.println("拦截了 manage");
// 从请求头中获取token
String token = request.getHeader("token");
// System.out.println(token);
// 判断token是否正确
if(token == null || token.equals("token")){
// System.out.println("未登入");
return false;
}
// 解析token
if(!TokenUtils.verify(token)){
// System.out.println("解析失败");
return false;
}
return true;
}
}

不要忘记把拦截器加入到配置中,说明你需要拦截的内容

private TokenInterceptor interceptor;
@Autowired//装配拦截器
public void setInterceptor(TokenInterceptor interceptor) {
this.interceptor = interceptor;
}
//解决跨域请求
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//放行哪些原始域
.allowedOriginPatterns(ConstUtils.PATH_ORIGIN)
//是否发送Cookie
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE")
.maxAge(30*1000)
.allowedHeaders("*")
.exposedHeaders("*");
}
//配置拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(interceptor)
.addPathPatterns("/manage/**");
}

登录请求的Controller

/**
* 登入功能
* @param user 前端的用户登入信息
* @return 返回登录情况
*/
@PostMapping("/login/{user}")
public Map<String,Object> login(@PathVariable String user){
Map<String,Object> userMap = JSONObject.parseObject(user, (Type)Map.class);
Map<String,Object> result = new HashMap<>();
// 登入验证
if(loginService.login(userMap)){
// 登入成功
User userToken = new User();
// 设置token
userToken.setUserCode((String) userMap.get("userCode"));
userToken.setUserCode((String) userMap.get("userPassword"));
String token = TokenUtils.sign(userToken);
result.put("token",token);
result.put("userCode",userMap.get("userCode"));
// 设置返回信息
result.put("msg",ConstUtils.LOGIN_SUCCESS);
result.put("is_login",true);
}else {
// 登入失败
result.put("msg",ConstUtils.LOGIN_FAILURE);
result.put("is_login",false);
}
return result;
}

这样就大工完成了

测试看看吧:

总结下

其实这就是在加密与解密,利用到了一些http请求的知识,你也可以自己设计加密与解密!!!

没有多么的神奇

posted @   水三丫  阅读(1364)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示