后端:
<!--token--> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version> </dependency>
/** * @author :ZWQ * @version :1.0 * @date :2019/10/16 - 18:52 * @description : */ @Service public class TokenService { public String getToken(User user) { Date start = new Date(); long currentTime = System.currentTimeMillis() + 60* 60 * 1000;//一小时有效时间 Date end = new Date(currentTime); String token = ""; token = JWT.create().withAudience(user.getUserId().toString()).withIssuedAt(start).withExpiresAt(end) .sign(Algorithm.HMAC256(user.getPassword())); return token; } }
@RestController @RequestMapping("/user") public class UserController { @Autowired UserService userService; @Autowired TokenService tokenService; /** * 登录方法 * @param request * @return ModelAndView */ @RequestMapping("/login") public String login(@RequestBody User user, HttpServletRequest request) { System.out.println(user.getUserName()+" "+user.getPassword()); User userForBase=userService.getUserByUsername(user.getUserName(), user.getPassword()); System.out.println("------------------------------"+userForBase); if(userForBase==null){ String msg = "用户名或者密码错误"; return msg; } String token = tokenService.getToken(userForBase); System.out.println(token); return token; } /*测试token 不登录没有token*/ @UserLoginToken @GetMapping("/getMessage") public String getMessage(){ return "你已通过验证"; }
package com.springboot.interceptor; 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.springboot.annotation.PassToken; import com.springboot.annotation.UserLoginToken; import com.springboot.pojo.User; import com.springboot.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.lang.reflect.Method; /** * @author :ZWQ * @version :1.0 * @date :2019/10/16 - 18:47 * @description :拦截器去获取token并验证token */ public class AuthenticationInterceptor implements HandlerInterceptor { @Autowired UserService userService; @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object object) throws Exception { String token = httpServletRequest.getHeader("token");// 从 http 请求头中取出 token // 如果不是映射到方法直接通过 if (!(object instanceof HandlerMethod)) { return true; } HandlerMethod handlerMethod = (HandlerMethod) object; Method method = handlerMethod.getMethod(); //检查是否有passtoken注释,有则跳过认证 if (method.isAnnotationPresent(PassToken.class)) { PassToken passToken = method.getAnnotation(PassToken.class); if (passToken.required()) { return true; } } //检查有没有需要用户权限的注解 if (method.isAnnotationPresent(UserLoginToken.class)) { UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class); if (userLoginToken.required()) { // 执行认证 if (token == null) { throw new RuntimeException("无token,请重新登录"); } // 获取 token 中的 user id String userId = null; int id = Integer.parseInt(userId); try { userId = JWT.decode(token).getAudience().get(0); } catch (JWTDecodeException j) { throw new RuntimeException("401"); } User user = userService.findUserById(id); if (user == null) { throw new RuntimeException("用户不存在,请重新登录"); } // 验证 token JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build(); try { jwtVerifier.verify(token); } catch (JWTVerificationException e) { throw new RuntimeException("401"); } return true; } } return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { } }
package com.springboot.config; import com.springboot.interceptor.AuthenticationInterceptor; 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; /** * @author :ZWQ * @version :1.0 * @date :2019/10/16 - 18:49 * @description : */ @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authenticationInterceptor()) .addPathPatterns("/**"); // 拦截所有请求,通过判断是否有 @LoginRequired 注解 决定是否需要登录 } @Bean public AuthenticationInterceptor authenticationInterceptor() { return new AuthenticationInterceptor(); } }
package com.springboot.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author :ZWQ * @version :1.0 * @date :2019/10/16 - 18:44 * @description :用来跳过验证的PassToken */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface PassToken { boolean required() default true; }
package com.springboot.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author :ZWQ * @version :1.0 * @date :2019/10/16 - 18:46 * @description :需要登录才能进行操作的注解UserLoginToken */ @Target({ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface UserLoginToken { boolean required() default true; }
methods: {
login (LoginForm) {
this.$refs[LoginForm].validate( valid =>{
if(valid){
this.$axios.post(‘/user/login‘,this.loginForm).then( res =>{
//登陆成功 使用token
const token = res.data;
console.log(token);
/*存储到ls*/
localStorage.setItem(‘eleToken‘,token);
/*解析token中的信息*/
const decoded = jwt(token);
/*存储至vuex*/
this.$store.dispatch("setAuthenticated",!this.isEmpty(decoded)) //decoded空,函数返回真,取反假
this.$store.dispatch("setUser",decoded)
/*跳转*/
this.$router.push(‘/index‘);
})
}
})
},
isEmpty(value){
return(
value ===undefined || value ===null ||
(typeof value === "object" && Object.keys(value).length ===0) ||
(typeof value ==="string" && value.trim().length ===0)
);
}
}
/**
* axios请求配置
*/
import axios from ‘axios‘
import { Loading } from ‘element-ui‘; /*elementUI的loading*/
import { Message } from ‘element-ui‘; /*elementUI消息提醒*/
/*import { Message,Loading } from ‘element-ui‘; 也可以这样解构赋值*/
import router from ‘../router/index‘
let loading;
function startLoading () {
loading = Loading.service({ /*在需要调用时:*/
lock: true,
text: ‘拼命加载中...‘,
background: ‘rgba(0,0,0,0,7)‘
});
}
function endLoading () {
loading.close();
}
//请求拦截
axios.interceptors.request.use(config => {
//加载动画
startLoading();
/*判断token存在 登录拦截*/
if(localStorage.eleToken){
/*设置统一的header*/
config.headers.Authorization = localStorage.eleToken;
}
return config;
},error => {
return Promise.reject(error);
});
//响应拦截
axios.interceptors.response.use(Response => {
//结束加载动画
endLoading();
return Response;
},error => {
//错误提醒
endLoading();
Message.error(error.response.data);
/*获取错误状态码*/
const { status } =error.response;
if(status == 401){
Message.error("token失效,重新登录");
/*清楚token*/
localStorage.removeItem(‘eleToken‘);
/*跳转登录*/
router.push(‘/‘)
}
return Promise.reject(error);
})
export default axios;
import Vue from ‘vue‘;
import Vuex from ‘vuex‘;
Vue.use(Vuex)
const types ={
SET_AUTHENTICATED: ‘SET_AUTHENTICATE‘,
SET_USER: ‘SET_USER‘,
};
const state = {
isAuthenticated: false,
user: {}
};
const getters ={
isAuthenticated: state =>state.isAuthenticated,
user: state => state.user
};
const mutations ={
[types.SET_AUTHENTICATED](state,isAuthenticated){ /*设置是否授权*/
if(isAuthenticated) state.isAuthenticated = isAuthenticated;
else state.isAuthenticated = false;
},
/*类型,参数*/
[types.SET_USER](state,user){
if (user) state.user = user;
else state.user = {};
}
};
/*异步操作 调用mutations*/
const actions ={
setAuthenticated:( {commit},isAuthenticated) =>{
commit(types.SET_AUTHENTICATED,isAuthenticated);
},
setUser:({commit},user) =>{
commit(types.SET_USER,user);
}
};
export default new Vuex.Store({
state,
getters,
mutations,
actions
});
import Vue from ‘vue‘
import Router from ‘vue-router‘
import Index from ‘../pages/Index‘
import Login from ‘../pages/login/Login‘
import Registr from ‘../pages/login/Registr‘
import NotFound from ‘../pages/404‘
Vue.use(Router)
const router = new Router({
routes: [
{
path: ‘/‘,
name: ‘login‘,
component: Login
}, {
path: ‘/index‘,
name: ‘index‘,
component: Index
},{
path: ‘/register‘,
name: ‘register‘,
component: Registr
},{
path: ‘*‘,
name: ‘/404‘,
component: NotFound
}
]
})
/*路由守卫 根据登录获得token*/
router.beforeEach((to,from,next) =>{
const isLogin = localStorage.eleToken ? true :false ;
if(to.path ==="/" || to.path ==="/register"){
next();
}else{
isLogin ? next() :next("/") /*真跳转 假注册*/
}
})
export default router
<template> <div id="app"> <router-view/> </div> </template> <script> import jwt from ‘jwt-decode‘; export default { name: "App", comments:{}, created(){ /*在根组件进行判断,否则刷新就没了*/ if (localStorage.eleToken){ const decoded = jwt(localStorage.eleToken); /*存储至vuex*/ this.$store.dispatch("setAuthenticated",!this.isEmpty(decoded)) this.$store.dispatch("setUser",decoded) } }, methods: { isEmpty(value){ return( value ===undefined || value ===null || (typeof value === "object" && Object.keys(value).length ===0) || (typeof value ==="string" && value.trim().length ===0) ); } } }; </script> <style> #app { font-family: ‘Avenir‘, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from ‘vue‘ import App from ‘./App‘ import router from ‘./router‘ import ElementUI from ‘element-ui‘; import ‘element-ui/lib/theme-chalk/index.css‘; import axios from ‘./api/http‘ /*配置axios*/ import store from ‘./store/index‘ Vue.use(ElementUI); Vue.config.productionTip = false Vue.prototype.$axios = axios axios.defaults.baseURL =‘/api‘; /* eslint-disable no-new */ new Vue({ el: ‘#app‘, router, store, components: { App }, template: ‘<App/>‘ })
原文:https://www.cnblogs.com/zwq20134/p/11687820.html