vue springboot实现token登录以及访问验证
vue springboot实现token登录以及访问验证后端代码:pom依赖:<!--fastjson依赖,用户一会儿前端传值,转换json数据--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version&g
·
vue springboot实现token登录以及访问验证
后端代码:
pom依赖:
<!--fastjson依赖,用户一会儿前端传值,转换json数据-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.71</version>
</dependency>
<!--jwt 依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
TokenUtil:
package com.example.demo.jwt;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.example.demo.entity.User;
import java.util.Date;
public class TokenUtil {
private static final long EXPIRE_TIME= 15*60*1000;
private static final String TOKEN_SECRET="tokenqkj"; //密钥盐
/**
* 签名生成
* @param user
* @return
*/
public static String sign(User user){
String token = null;
try {
Date expiresAt = new Date(System.currentTimeMillis() + EXPIRE_TIME);
token = JWT.create()
.withIssuer("auth0")
.withClaim("username", user.getUsername())
.withExpiresAt(expiresAt)
// 使用了HMAC256加密算法。
.sign(Algorithm.HMAC256(TOKEN_SECRET));
} catch (Exception e){
e.printStackTrace();
}
return token;
}
/**
* 签名验证
* @param token
* @return
*/
public static boolean verify(String token){
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(TOKEN_SECRET)).withIssuer("auth0").build();
DecodedJWT jwt = verifier.verify(token);
System.out.println("认证通过:");
System.out.println("issuer: " + jwt.getIssuer());
System.out.println("username: " + jwt.getClaim("username").asString());
System.out.println("过期时间: " + jwt.getExpiresAt());
return true;
} catch (Exception e){
return false;
}
}
}
TokenInterceptor:token拦截器
package com.example.demo.jwt;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
@Component
public class TokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler)throws Exception{
if(request.getMethod().equals("OPTIONS")){
response.setStatus(HttpServletResponse.SC_OK);
return true;
}
response.setCharacterEncoding("utf-8");
String token = request.getHeader("token");
if(token != null){
boolean result = TokenUtil.verify(token);
if(result){
System.out.println("通过拦截器");
return true;
}
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try{
JSONObject json = new JSONObject();
json.put("success","false");
json.put("msg","认证失败,未通过拦截器");
json.put("code","50000");
response.getWriter().append(json.toJSONString());
System.out.println("认证失败,未通过拦截器");
// response.getWriter().write("50000");
}catch (Exception e){
e.printStackTrace();
response.sendError(500);
return false;
}
return false;
}
}
IntercepterConfig:入口拦截
package com.example.demo.jwt;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
* 拦截器配置
*/
@Configuration
public class IntercepterConfig implements WebMvcConfigurer {
private TokenInterceptor tokenInterceptor;
//构造方法
public IntercepterConfig(TokenInterceptor tokenInterceptor){
this.tokenInterceptor = tokenInterceptor;
}
@Override
public void addInterceptors(InterceptorRegistry registry){
List<String> excludePath = new ArrayList<>();
excludePath.add("/user_register"); //注册
excludePath.add("/login"); //登录
excludePath.add("/logout"); //登出
excludePath.add("/static/**"); //静态资源
excludePath.add("/swagger-ui.html/**"); //静态资源
excludePath.add("/assets/**"); //静态资源
registry.addInterceptor(tokenInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludePath);
WebMvcConfigurer.super.addInterceptors(registry);
}
/**
* 跨域支持
*
* @param registry
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT", "PATCH", "OPTIONS", "HEAD")
.maxAge(3600 * 24);
}
}
现在是登录接口,当然,记得配置跨域:
CorsConfig
package com.example.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
/*是否允许请求带有验证信息*/
corsConfiguration.setAllowCredentials(true);
/*允许访问的客户端域名*/
corsConfiguration.addAllowedOrigin("*");
/*允许服务端访问的客户端请求头*/
corsConfiguration.addAllowedHeader("*");
/*允许访问的方法名,GET POST等*/
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
登录接口:(我这里用的是mybatisplus)
@PostMapping("/login")
public ResultMap toLogin(HttpServletResponse response,@RequestBody JSONObject obj){
System.out.println(obj);
// String scope= JSONObject.parseObject(obj).getJSONObject("data").getString("scope");
QueryWrapper<User> wrapper=new QueryWrapper<>();
obj.getString("password");
wrapper
.eq("username",obj.getString("username"))
.eq("password",obj.getString("password"));
String token=null;
User user = userService.getOne(wrapper);
if(user!=null){
token = TokenUtil.sign(user);
}
// 将token放在响应头
// response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, JwtTokenUtil.TOKEN_PREFIX + token);
if(token != null){
return resultMap.success().code(200).message(token);
}
return resultMap.success().code(400).message("登录失败,请重试");
}
现在是vue:(首先安装vuex,我主要是写后端的,感觉这个是个全局变量)
src目录下创建store文件夹,store下 index.js:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
token: localStorage.getItem('token') ? localStorage.getItem('token') : ''
},
mutations: {
setToken (state,token) {
state.token =token;
localStorage.setItem("token",token.token); //存储token
},
delToken (state) {
state.token = '';
localStorage.removeItem("token"); //删除token
}
}
});
export default store;
然后登录业务(我这里加了element ui 所以看着有点乱,表单验证可以不看,记得在上面引入vuex下的方法,因为main.js没有引入)
<script>
import { mapMutations } from 'vuex';
export default {
data(){
return{
loginForm: {
username:'',
password:''
},
//这里是表单验证
loginFormRules:{
username:[
{ required: true, message: '请输入用户名称', trigger: 'blur' },
{ min: 2, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
],
password:[
{ required: true, message: '请输入用户名称', trigger: 'blur' },
{ min: 3, max: 10, message: '长度在 3 到 5 个字符', trigger: 'blur' }
]
}
}
},
methods:{
//这里是重置按钮,根据¥$refs.xxx获取到东西
loginFromReset(){
this.$refs.loginFormRef.resetFields();
},
//这里是登录了,先与验证
// ...mapMutations(['changeLogin']),
...mapMutations(['setToken']),
login(){
let _this =this;
this.$refs.loginFormRef.validate(async valid=>{
if(!valid){
return this.$message.error('请正确填入相应数据');
}else{
const resu = await this.$http.post('login',this.loginForm);
console.log(resu.data)
if(resu.data.code==200){
this.$message.success('登录成功')
//把token存进localStorage里面
// window.localStorage.setItem("token",resu.data.token)
console.log(resu.data.message)
this.setToken({token: resu.data.message });
// this.$store.commit.changeLogin({ token: resu.data.token });
this.$router.push({name: 'me'})
}else{
return this.$message.error('登录失败');
}
}
});
}
}
}
</script>
然后添加路由守卫:
//挂载路由导航守卫
router.beforeEach((to,from,next)=>{
//to 将要访问的路径
//from 代表从哪个路径而来
//next() 代表放行 next('xxx') 强制放行的xxx的路径
if(to.path==='/'||to.path==='/login'){
next();
}else{
const tokenStr=window.localStorage.getItem('token')
if(!tokenStr){
return next('/login')
}
next()
}
})
最后main.js中添加请求拦截器:(这里的config.headers.token中的token是后台定义的要从请求头中那的那个名:{String token = request.getHeader(“token”);}中的token)
// 添加请求拦截器,在请求头中加token
axios.interceptors.request.use(
config => {
if (localStorage.getItem('token')) {
config.headers.token = localStorage.getItem('token');
}
return config;
},
error => {
return Promise.reject(error);
});
现在运行:可以看到localStorage中没有token
现在登录
这里登录成功以后存储了token,然后看看后台
后台也通过验证,现在试试把token清除然后刷新页面
刷新
重定向到登录页,大功告成!
更多推荐
已为社区贡献1条内容
所有评论(0)