100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > springboot + vue 后台token生成 拦截器 redis实现 前台封装axios xueX 接口实现

springboot + vue 后台token生成 拦截器 redis实现 前台封装axios xueX 接口实现

时间:2020-07-16 06:26:16

相关推荐

springboot + vue 后台token生成 拦截器 redis实现  前台封装axios xueX 接口实现

后台

后台程序图片

新建token的基础类

public class Constants {public final static String TOKEN = "token";}

配置redis

pom.xml中添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>

application.yml中配置(注意在spring下)

server:port: 8088spring:redis:database: 0host: localhostport: 6379timeout: 10000mspassword:jedis:pool:max-active: 200max-wait: -1msmax-idle: 8min-idle: 0token:#登录生成的token在redis中保存的有效期,单位:秒expires: 1000timeout: trueaes:#AES登录密码加密的私钥,要求长度必须为16位。key: hj7x89HTyuBI0452

添加redis工具类

/*** redis 数据操作工具类*/@Componentpublic class RsUtil {@Resourcepublic RedisTemplate<String, String> redisTemplate;@Autowiredpublic PropertiesConfig properties;/*** 将数据插入redis** @param key 索引* @param value 值*/public void set(String key, String value) {ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();if (properties.isTimeout()) {valueOperations.set(key, value, properties.getTokenExpires().longValue(), TimeUnit.SECONDS);} else {valueOperations.set(key, value);}}/*** 删除redis中数据** @param key 索引*/public void del(String key) {ValueOperations<String, String> vo = redisTemplate.opsForValue();RedisOperations<String, String> operations = vo.getOperations();operations.delete(key);}/*** 查询redis中数据** @param key 索引* @return 查询结果*/public String get(String key) {ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();String value = valueOperations.get(key);if (value != null && !value.equals("")) {set(key, value);}return value;}}

至此redis已配置完,接下来开始配置拦截器

首先配置下依赖 fastjson 依赖 (json-object数据转换)

<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.69</version></dependency>

先写一个请求信息获取类ServletUtils

/*** 请求信息获取工具类*/public class ServletUtils {/*** 获取配置信息* @return 配置信息*/public static ServletRequestAttributes getRequestAttributes() {RequestAttributes attributes = RequestContextHolder.getRequestAttributes();return (ServletRequestAttributes) attributes;}/*** 获取请求信息* @return 请求信息*/public static HttpServletRequest getRequest() {return getRequestAttributes().getRequest();}/*** 获取返回信息* @return 返回信息*/public static HttpServletResponse getResponse() {return getRequestAttributes().getResponse();}/*** 获取指定header信息* @param header 指定header信息* @return header信息*/public static String getHeader(String header) {return getRequestAttributes().getRequest().getHeader(header);}/*** 获取session信息* @return session信息*/public static HttpSession getSession() {return getRequest().getSession();}}

再在config包下新建一个系统配置信息读取类PropertiesConfig

/*** 系统配置信息读取类*/@Componentpublic class PropertiesConfig {/*** token有效时间**/@Value("${token.expires}")private Integer tokenExpires;/*** 密码加密私钥**/@Value("${aes.key}")private String aesKey;/*** 是否设置token超时*/@Value("${token.timeout}")private boolean timeout;/*** 取得加密私钥** @return 加密私钥*/public String getAesKey() {return aesKey;}/*** 设定加密私钥** @param aesKey 加密私钥*/public void setAesKey(String aesKey) {this.aesKey = aesKey;}/*** 取得token有效时间** @return token有效时间*/public Integer getTokenExpires() {return tokenExpires;}/*** 设定token有效时间** @param tokenExpires token有效时间*/public void setTokenExpires(Integer tokenExpires) {this.tokenExpires = tokenExpires;}/*** 取得token是否超时** @return token是否超时*/public boolean isTimeout() {return timeout;}/*** 设定token是否超时** @param timeout 是否超时*/public void setTimeout(boolean timeout) {this.timeout = timeout;}}

新建包.handler添加拦截器的类RequestInterceptorHandler

/*** HTTP请求拦截器*/public class RequestInterceptorHandler implements HandlerInterceptor {private static Logger logger = LoggerFactory.getLogger(RequestInterceptorHandler.class);@Autowiredpublic RsUtil rsUtil;/*** 拦截器拦截请求** @param request 请求体* @param response 请求结果* @param handler 其他* @return 请求结果*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {try {response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Headers", "content-type,token");response.setHeader("Access-Control-Allow-Method", "*");if (!request.getRequestURI().equals("/rest/admin/login")// 特殊接口不拦截 登录接口&& !request.getRequestURI().equals("/res/admin/logout") // 特殊接口不拦截 登出接口) {if (!request.getMethod().equals("OPTIONS")) {String token = request.getHeader(Constants.TOKEN);// token是否为空 redis的token是否过期 前后的token与Redis中保存的token是否相同if (token == null || token.equals("") || rsUtil.get("token") == null) {response.setContentType("application/json;charset=utf-8");PrintWriter out = response.getWriter();Map<String, Object> message = new HashMap<>();message.put("msg", "用户信息已过期");message.put("code", "1101");out.write(new ObjectMapper().writeValueAsString(message));out.flush();out.close();return false; // 直接可以返回到前台 前后用response.code接受就等于1101}}}return HandlerInterceptor.super.preHandle(request, response, handler);} catch (Exception e) {logger.info(e.getMessage());}return false;}}

然后配置装载上面的拦截器类,放入spring容器内运行

/***拦截器*/@Configurationpublic class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(getMyInterceptor()).addPathPatterns("/rest/**"); // 拦截所有/rest的请求}@Beanpublic RequestInterceptorHandler getMyInterceptor(){return new RequestInterceptorHandler();// 自己定义写的拦截器}}

在controller中登录接口获取token保存到redis并返回给前台

@ApiOperation("login")@ApiImplicitParams({})@ResponseBody@RequestMapping(value = "/login", method = RequestMethod.POST)public ReturnDto login(@RequestBody UserDto user) {String token = CommonUtils.getRandom();rsUtil.set("token", token);if (user.getUsername().equals("admin") && user.getPassword().equals("123456")) {return CommonUtils.returnDto(rsUtil.get("token"));} else {return new ReturnDto(ResultCodeUtil.FAIL);}}

前台

首先引入vuex axios

创建store文件添加vuex基础信息,在main.js中使用,这个主要作用存储token

使用方法 this.$mit(‘setToken’,response.body.res) // 将后台传的token存入进去,相当于公共变量

import Vue from 'vue'import Vuex from 'vuex'Vue.use(Vuex)export default new Vuex.Store({namespaced: true,state: {token: '',nowTime: ''},mutations: {//相当于getset方法setToken (state,token) {state.token =token;localStorage.setItem('token',token);//存储token},delToken (state) {state.token = '';localStorage.removeItem('token'); //删除token},setNowTime (state,nowTime) {state.nowTime =nowTime;localStorage.setItem('nowTime',nowTime);//存储token时间},delNowTime (state) {state.nowTime = '';localStorage.removeItem('nowTime'); //删除token时间}}})

封装axios接口,首先解决跨域问题,进行替代修改config中的index文件

dev: {// PathsassetsSubDirectory: 'static',assetsPublicPath: '/',proxyTable: {'/rest': {target: 'http://localhost:8088',changeOrigin: true,pathRewrite: {'^/rest': '/rest' //实际请求去掉/rest以空字符串代替}}},

创建一个axios的实例,然后写公共方法get,post,之后再main.js暴露出去,进行全局使用

import axios from 'axios'import store from '../store'axios.defaults.baseURL = 'http://localhost:8080';// 请求超时时间axios.defaults.timeout = 10000;// request interceptor(请求拦截器)axios.interceptors.request.use(config => {config.headers = {'Content-Type':'application/json;charset=UTF-8' //配置请求头}if (config.method === 'post') {config.data = JSON.stringify(config.data)}if (localStorage.getItem('token')) { // 判断是否存在token,如果存在的话,则每个http header都加上tokenconfig.headers.token = localStorage.getItem('token');}return config},error => {// do something with request errorconsole.log(error) // for debugreturn Promise.reject(error)})// response interceptor(接收拦截器)axios.interceptors.response.use(response => {var today = new Date().getTime();if(localStorage.getItem('nowTime')!=null){if(today-localStorage.getItem('nowTime')>1000*60){ //如果第一次请求后在第二次请求大于1分钟就进行到登入页。localStorage.removeItem('token'); localStorage.removeItem('nowTime');location.href = '/' //重新定向到登录页面return;}else{//如果小于的话并且token改变就替换tokenlocalStorage.removeItem('nowTime');mit('setNowTime',today) //每一次请求都会添加新的一个时间从而进行保存。}}else{ //如果是今天第一次请求的话那就把时间添加进去。// var today = new Date().getTime();mit('setNowTime',today) //退出登入后再一次登入会进行添加这一次登入时间。}return response},error => {if (error.response) {switch (error.response.status) {case 401:// 返回 401 清除token信息并跳转到登录页面localStorage.removeItem('token');location.href = '/' //重新定向到登录页面}}return Promise.reject(error)})/** * get方法,对应get请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */export function get(url, params){ return new Promise((resolve, reject) =>{ axios.get(url, { params: params }) .then(res => { resolve(res.data); }) .catch(err => { reject(err.data) }) });}/** * post方法,对应post请求 * @param {String} url [请求的url地址] * @param {Object} params [请求时携带的参数] */export function post(url, params) { return new Promise((resolve, reject) => { axios.post(url, params) .then(res => { resolve(res.data); }) .catch(err => { reject(err.data) }) });}

main.js

// 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'//axios 添加原型import { get,post } from './utils/request.js'import store from './store'Vue.config.productionTip = falseVue.use(ElementUI, {size: 'small'})Vue.prototype.$get = getVue.prototype.$post = post//表示你没有退出登入时候如果你不小心关掉了页面后第二次进去不要登入可以直接进入。router.beforeEach((to, from, next) => {if (to.path == '/') {var f=localStorage.getItem("token");if (f) {next();} }var ff=localStorage.getItem("token");if (!ff && to.path != '/') {next({ path: '/' })} else {next()}})/* eslint-disable no-new */new Vue({el: '#app',router,store,components: { App },template: '<App/>'})

login登录页面使用

let _this = this_this.$post('/rest/admin/login', {username: 'admin',password: '123456'}).then(function (response) {let code = response.codeif (code === 0) {_this.$mit('setToken',response.body.res)//保存后台传过来的token_this.$router.push({path: '/success',query: { data: response.body }})} else {_this.$router.push({path: '/error',query: { message: response.message }})}console.log(response);}).catch(function (error) {console.log(error);});}

普通页面使用

this.$post('/rest/admin/user',{username: 'admin',password: '123456'}).then(function (response) {debuggerif (response.code === "1101") {console.log(response); // 用户已过期}console.log(response);}).catch(function (error) {console.log(error);});

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。