今天准备做sso的时候,突然发现vue请求头还是要记录一下的,虽然不是专业前端。
后端生成token
导入依赖:
<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
自己写了一个Jwt的小工具类:
package com.xii.springboot_mybatis.utils;
import io.jsonwebtoken.*;
import java.util.Date;
import java.util.UUID;
public class JwtUtil {
//生成
public static String getToken(Integer userId,String username){
JwtBuilder builder = Jwts.builder();
String token = builder//header 头部
.setHeaderParam("type", "JWT")
.setHeaderParam("alg", "HS256")
//payloa载体 有效载荷
.claim("user_id", userId)
.claim("username", username)
//主题
.setSubject("admin-test")
.setExpiration(new Date(System.currentTimeMillis() + (60 * 1000)))
.setId(UUID.randomUUID().toString())
//签名
.signWith(SignatureAlgorithm.HS256, "wxhtt")
.compact();//生成
return token;
}
/**
* 解析
*/
public static Boolean parseToken(String token){
try {
JwtParser parser = Jwts.parser();
Jwt<Header, Claims> result = parser
.setSigningKey("wxh")
.parseClaimsJwt(token);
Claims claims = result.getBody();
System.out.println("ID:" + claims.get("userId"));
System.out.println("角色:" + claims.get("username"));
System.out.println("Id:" + claims.getId());
System.out.println("签名" + claims.getSubject());
System.out.println("有效期" + claims.getExpiration());
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}
控制层:
@PostMapping("selectPassWordUserName")
public Result selectPassWordUserName(@RequestBody Map<String,String> userpass){
Map<String,Object> stringStringMap = sysUserService.selectPassWordUserName(userpass.get("username"), userpass.get("password"));
System.out.println(stringStringMap);
Integer userId = (Integer) stringStringMap.get("userId");
String token = JwtUtil.getToken(userId,(String) stringStringMap.get("username"));
System.out.println(token);
if(stringStringMap.size() > 0){
return new Result(2000,"登录成功!",token);
}else {
return new Result(2000,"登录失败!",null);
}
}
Vue前端的登录请求
this.$refs[formName].validate((valid) => {
if (valid) {
// alert('submit!');
var _this = this;
this.$http.post('/sysUser/selectPassWordUserName',{
username: this.ruleForm.pass,
password: this.ruleForm.checkPass
})
.then(response=>{
// console.log(response.data.data)
//本地存储 没有过期时间
// localStorage.setItem("token",JSON.stringify(response.data.data))
cookie.set("token",response.data.data) //未设置cookies的过期时间 默认单位是天
// let timer = setInterval(() => {
// //需要定时执行的代码
// console.log(cookie.get("token"))
// },1000)
})
} else {
console.log('error submit!!');
return false;
}
});
下面的并不完善 但是可以了解下原理:
token可以存在localStorage(本地存储中),也可以存在cookies中,在header中设置token为了在每一个发送到后端的请求都可以从header中获取token值来验证。
下面的router.beforeEach是每一个页面的请求都会判断是否有token没有的话禁止访问。
在mian.js中
// 添加请求拦截器,在请求头中加token //为请求头对象,添加Token 验证的Authorization 字段
axios.interceptors.request.use(
config => {
// console.log(localStorage.getItem("token"))
if (localStorage.getItem("token")) {
config.headers.Authorization = "JWT " + localStorage.getItem("token");
}
return config;
},
error => {
return Promise.reject(error);
}
);
// 使用 router.beforeEach 注册一个全局前置守卫,判断用户是否登陆
router.beforeEach((to, from, next) => {
if (to.path === '/Login') {
next();
} else {
// let token = localStorage.getItem('token');
let token = cookies.get('token');
console.log('请求:'+token=='undefined')
if (token === null || token === '' || token === undefined) {
//如果没有登录,跳转到登录页面
next('/Login');
} else {
if (to.matched.length === 0) { //没有匹配到当前路由 则 404
next('/404')
} else {
next();
}
}
}
});