最近在做一个前后端分离项目,研究了好几天终于搞出来了,在此跟小伙伴分项一下,同时记录一下方便以后自己查阅,系统架构用的是SpringBoot2+SpringSecurity+JWT+VUE(ElementUI) 。
业务需求:做大屏数据可视化,跟后台业务token 分开,将大屏配置表信息存到redis中,通过token 可以查询到。 用户访问大屏后台接口要带上Authorization ,访问前先校验token。校验通过则可以执行接口,并返回token 里存储的信息给接口调用。
大屏数据可视化有专门配置表:
redis 存储格式:large_screen_login_tokens:六位随机码:UUID
需要实现从浏览器输入六位随机码后先从redis 里查询是否有token如果存在并且不超期,则直接将token 返回前端;如果redis 里不存在则重新生成,如果超期则刷新token,同时将大屏配置信息保存到redis 。
代码编写:1.SecurityConfig 配置类:
package com.dechnic.framework.config; import com.dechnic.framework.security.filter.JwtAuthenticationTokenFilter; import com.dechnic.framework.security.handle.AuthenticationEntryPointImpl; import com.dechnic.framework.security.handle.LogoutSuccessHandlerImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpMethod; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.web.filter.CorsFilter; @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) public class SecurityConfig extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Autowired private AuthenticationEntryPointImpl unauthorizedHandler; @Autowired private LogoutSuccessHandlerImpl logoutSuccessHandler; @Autowired private JwtAuthenticationTokenFilter authenticationTokenFilter; @Autowired private CorsFilter corsFilter; @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { httpSecurity // CSRF禁用,因为不使用session .csrf().disable() // 认证失败处理类 .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() // 基于token,所以不需要session .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() // 过滤请求 .authorizeRequests() // 对于登录login 验证码captchaImage 允许匿名访问 .antMatchers("/login", "/captchaImage").anonymous() .antMatchers( HttpMethod.GET, "*.html", "*.css", "*.js" ).permitAll() .antMatchers("/profileapi-docs").anonymous() .antMatchers("/druid @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() { return new BCryptPasswordEncoder(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); } }
2.JwtAuthenticationTokenFilter
package com.dechnic.framework.security.filter; import com.dechnic.common.core.domain.model.LoginUser; import com.dechnic.common.utils.SecurityUtils; import com.dechnic.common.utils.StringUtils; import com.dechnic.framework.web.service.TokenService; import com.dechnic.nh.module.LoginLargeScreenUser; import com.dechnic.nh.security.LargeScreenAuthenticationToken; import com.dechnic.nh.service.impl.LargeScreenTokenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Component public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { @Autowired LargeScreenTokenService largeScreenTokenService; @Autowired private TokenService tokenService; private static final String largeScreenUrlPrifix = "nh/LargeScreen"; private static final String [] passUrls = {"nh/auth/login"}; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { boolean passFlag = false; String reqPath = request.getRequestURI(); for (String pass : passUrls){ if (reqPath.indexOf(pass)!=-1){ passFlag = true; break; } } if (passFlag){ chain.doFilter(request, response); }else { int urlIndex = reqPath.indexOf(largeScreenUrlPrifix); boolean flag = true; if (urlIndex != -1) { flag = false; } if (flag) { LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication())) { tokenService.verifyToken(loginUser); UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities()); authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authenticationToken); } } else { // 处理能耗大屏展示 LoginLargeScreenUser loginLargeScreenUser = largeScreenTokenService.getLoginLargeScreenUser(request); if (StringUtils.isNotNull(loginLargeScreenUser)) { largeScreenTokenService.verifyToken(loginLargeScreenUser); LargeScreenAuthenticationToken largeScreenAuthenticationToken = new LargeScreenAuthenticationToken(loginLargeScreenUser,null); largeScreenAuthenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(largeScreenAuthenticationToken); } } chain.doFilter(request, response); } } }
3.LargeScreenAuthenticationToken
package com.dechnic.nh.security; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; import java.util.Collection; public class LargeScreenAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = 1L; private final Object principal; public LargeScreenAuthenticationToken(Object principal) { super(null); this.principal = principal; setAuthenticated(false); } public LargeScreenAuthenticationToken(Object principal,Collection extends GrantedAuthority> authorities) { super(authorities); this.principal = principal; super.setAuthenticated(true); } @Override public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException { if (isAuthenticated) { throw new IllegalArgumentException( "Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead"); } super.setAuthenticated(false); } @Override public Object getCredentials() { return null; } @Override public Object getPrincipal() { return this.principal; } }
4.AuthenticationEntryPointImpl
package com.dechnic.framework.security.handle; import com.alibaba.fastjson.JSON; import com.dechnic.common.constant.HttpStatus; import com.dechnic.common.core.domain.AjaxResult; import com.dechnic.common.utils.ServletUtils; import com.dechnic.common.utils.StringUtils; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.Serializable; @Component public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint, Serializable { private static final long serialVersionUID = -8970718410437077606L; @Override public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) throws IOException { int code = HttpStatus.UNAUTHORIZED; String msg = StringUtils.format("请求访问:{},认证失败,无法访问系统资源", request.getRequestURI()); ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(code, msg))); } }
5.LogoutSuccessHandlerImpl
package com.dechnic.framework.security.handle; import com.alibaba.fastjson.JSON; import com.dechnic.common.constant.Constants; import com.dechnic.common.constant.HttpStatus; import com.dechnic.common.core.domain.AjaxResult; import com.dechnic.common.core.domain.model.LoginUser; import com.dechnic.common.utils.ServletUtils; import com.dechnic.common.utils.StringUtils; import com.dechnic.framework.manager.AsyncManager; import com.dechnic.framework.manager.factory.AsyncFactory; import com.dechnic.framework.web.service.TokenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.security.core.Authentication; import org.springframework.security.web.authentication.logout.LogoutSuccessHandler; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Configuration public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler { @Autowired private TokenService tokenService; @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { String userName = loginUser.getUsername(); // 删除用户缓存记录 tokenService.delLoginUser(loginUser.getToken()); // 记录用户退出日志 AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); } ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.error(HttpStatus.SUCCESS, "退出成功"))); } }
6.大屏用户登陆LargeScreenAuthController
package com.dechnic.nh.controller; import com.alibaba.fastjson.JSONObject; import com.dechnic.common.core.domain.AjaxResult; import com.dechnic.nh.service.ILargeScreenUserLoginService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @Api("大屏用户登陆") @RestController @RequestMapping("/nh/auth") public class LargeScreenAuthController { @Autowired ILargeScreenUserLoginService largeScreenUserLoginService; @ApiOperation(value = "大屏用户登陆") @ApiImplicitParams({ @ApiImplicitParam(name = "uid", value = "uid", dataType = "String", required = true) }) @GetMapping("/login") public AjaxResult login(@RequestParam("uid")String uid) { return largeScreenUserLoginService.login(uid); } }
7.LargeScreenUserLoginServiceImpl
package com.dechnic.nh.service.impl; import com.dechnic.common.constant.Constants; import com.dechnic.common.constant.HttpStatus; import com.dechnic.common.core.domain.AjaxResult; import com.dechnic.common.utils.StringUtils; import com.dechnic.nh.entity.SysUserLargescreen; import com.dechnic.nh.module.LoginLargeScreenUser; import com.dechnic.nh.service.ILargeScreenUserLoginService; import com.dechnic.nh.service.ISysUserLargescreenService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Date; @Service public class LargeScreenUserLoginServiceImpl implements ILargeScreenUserLoginService { @Autowired ISysUserLargescreenService sysUserLargescreenService; @Autowired LargeScreenTokenService largeScreenTokenService; private DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); @Override public AjaxResult login(String uid) { if (StringUtils.isEmpty(uid)) { return AjaxResult.error(HttpStatus.FORBIDDEN,"uid 不能为空"); } SysUserLargescreen sysUserLargescreen = sysUserLargescreenService.getSysUserLargeScreenLoginByUid(uid); if (null == sysUserLargescreen){ return AjaxResult.error(HttpStatus.FORBIDDEN,"uid 不存在"); } Date validateTime = sysUserLargescreen.getValidateTime(); Instant instant = validateTime.toInstant(); LocalDateTime validTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime(); LocalDateTime now = LocalDateTime.now(); if (validTime.isBefore(now)){ return AjaxResult.error(HttpStatus.FORBIDDEN,"ValidateTime 已超期"); } LoginLargeScreenUser loginLargeScreenUser = new LoginLargeScreenUser(); loginLargeScreenUser.setSysUserLargescreen(sysUserLargescreen); loginLargeScreenUser.setUid(uid); String token = this.largeScreenTokenService.getRedisExitsTokenByUid(uid); if (StringUtils.isEmpty(token)){ // 创建新token token = largeScreenTokenService.createToken(loginLargeScreenUser); } loginLargeScreenUser.setToken(token); AjaxResult ajax = AjaxResult.success(); ajax.put(Constants.TOKEN,token); ajax.put("largeScreenInfo",loginLargeScreenUser); return ajax; } }
8.LargeScreenTokenService
package com.dechnic.nh.service.impl; import com.dechnic.common.constant.Constants; import com.dechnic.common.core.redis.RedisCache; import com.dechnic.common.utils.ServletUtils; import com.dechnic.common.utils.StringUtils; import com.dechnic.common.utils.ip.AddressUtils; import com.dechnic.common.utils.ip.IpUtils; import com.dechnic.common.utils.uuid.IdUtils; import com.dechnic.nh.module.LoginLargeScreenUser; import eu.bitwalker.useragentutils.UserAgent; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.TimeUnit; @Component public class LargeScreenTokenService { protected static final long MILLIS_SECOND = 1000; protected static final long MILLIS_MINUTE = 60 * MILLIS_SECOND; private static final Long MILLIS_MINUTE_TEN = 30 * 60 * 1000L; // 令牌自定义标识 @Value("${stoken.header}") private String header; // 令牌秘钥 @Value("${stoken.secret}") private String secret; // 令牌有效期(默认30分钟) @Value("${stoken.expireTime}") private int expireTime; @Autowired private RedisCache redisCache; public LoginLargeScreenUser getLoginLargeScreenUser(HttpServletRequest request) { // 获取请求携带的令牌 String token = getToken(request); if (StringUtils.isNotEmpty(token)) { Claims claims = parseToken(token); // 解析对应的权限以及用户信息 String uuid = (String) claims.get(Constants.LARGE_SCREEN_KEY); String lsKey = getTokenKey(uuid); LoginLargeScreenUser loginLargeScreenUser = redisCache.getCacheObject(lsKey); return loginLargeScreenUser; } return null; } public void setLoginLargeScreen(LoginLargeScreenUser loginLargeScreenUser) { if (StringUtils.isNotNull(loginLargeScreenUser) && StringUtils.isNotEmpty(loginLargeScreenUser.getToken())) { refreshToken(loginLargeScreenUser); } } public void delLoginUser(String token) { if (StringUtils.isNotEmpty(token)) { String userKey = getTokenKey(token); redisCache.deleteObject(userKey); } } public String createToken(LoginLargeScreenUser loginUser) { String token = StringUtils.isNotEmpty(loginUser.getToken())?loginUser.getToken():IdUtils.fastUUID(); loginUser.setToken(token); setUserAgent(loginUser); refreshToken(loginUser); Mapclaims = new HashMap<>(); claims.put(Constants.LARGE_SCREEN_KEY, loginUser.getUid() + ":" + token); return createToken(claims); } public void verifyToken(LoginLargeScreenUser loginUser) { long expireTime = loginUser.getExpireTime(); long currentTime = System.currentTimeMillis(); if (expireTime - currentTime <= MILLIS_MINUTE_TEN) { refreshToken(loginUser); } } public void refreshToken(LoginLargeScreenUser loginUser) { loginUser.setLoginTime(System.currentTimeMillis()); loginUser.setExpireTime(loginUser.getLoginTime() + expireTime * MILLIS_MINUTE); // 根据uuid将loginUser缓存 String userKey = getTokenKey(loginUser.getUid() + ":" + loginUser.getToken()); redisCache.setCacheObject(userKey, loginUser, expireTime, TimeUnit.MINUTES); } public void setUserAgent(LoginLargeScreenUser loginUser) { UserAgent userAgent = UserAgent.parseUserAgentString(ServletUtils.getRequest().getHeader("User-Agent")); String ip = IpUtils.getIpAddr(ServletUtils.getRequest()); loginUser.setIpaddr(ip); loginUser.setLoginLocation(AddressUtils.getRealAddressByIP(ip)); loginUser.setBrowser(userAgent.getBrowser().getName()); loginUser.setOs(userAgent.getOperatingSystem().getName()); } private String createToken(Map claims) { String token = Jwts.builder() .setClaims(claims) .signWith(SignatureAlgorithm.HS512, secret).compact(); return token; } private Claims parseToken(String token) { return Jwts.parser() .setSigningKey(secret) .parseClaimsJws(token) .getBody(); } public String getUsernameFromToken(String token) { Claims claims = parseToken(token); return claims.getSubject(); } private String getToken(HttpServletRequest request) { String token = request.getHeader(header); if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) { token = token.replace(Constants.TOKEN_PREFIX, ""); } return token; } private String getTokenKey(String uuid) { return Constants.LARGE_SCREEN_LOGIN_TOKEN_KEY + uuid; } public String getRedisExitsTokenByUid(String uid) { Collection keys = redisCache.keys(Constants.LARGE_SCREEN_LOGIN_TOKEN_KEY + uid+":*"); if (null != keys && keys.size() > 0) { for (String key : keys) { LoginLargeScreenUser loginLargeScreenUser = redisCache.getCacheObject(key); String token = createToken(loginLargeScreenUser); return token; } } return null; } }
9.application.yml
# 项目相关配置 dechnic: # 名称 name: tfoms # 版本 version: 1.0.0 # 版权年份 copyrightYear: 2021 # 实例演示开关 demoEnabled: true # 文件路径 示例( Windows配置D:/dechnic/uploadPath,Linux配置 /home/dechnic/uploadPath) profile: D:/dechnic/uploadPath # 获取ip地址开关 addressEnabled: false # 验证码类型 math 数组计算 char 字符验证 captchaType: math # 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8090 servlet: # 应用的访问路径 context-path: /bem_api tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # tomcat最大线程数,默认为200 max-threads: 800 # Tomcat启动初始化的线程数,默认值25 min-spare-threads: 30 # 日志配置 logging: level: com.dechnic: debug org.springframework: warn # Spring配置 spring: # 资源信息 messages: # 国际化资源文件路径 basename: i18n/messages profiles: active: test # 文件上传 servlet: multipart: # 单个文件大小 max-file-size: 10MB # 设置总上传的文件大小 max-request-size: 20MB # 服务模块 devtools: restart: # 热部署开关 enabled: true # token配置 token: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 30 # 大屏展示 stoken配置 stoken: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 60000000 # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.dechnic.**.entity,com.dechnic.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # PageHelper分页插件 pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: / # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice export default { name: 'showbi', data() { return { // uid:this.$route.query.uid uid:'RXQb3S' } }, created() { }, mounted() { this.goToBi() }, methods: { goToBi(){ // 此处调用后台接口 largeScreenLogin(this.uid).then(result=>{ if(result.code == 200){ setLargescreenToken(result.token) window.location.href = result.largeScreenInfo.sysUserLargescreen.bigscreenUrl } }) } } }
auth.js 将token 存到cookie
import cookies from 'js-cookie' const TokenKey = 'Admin-Token' export function getToken() { return cookies.get(TokenKey) } export function setToken(token) { return cookies.set(TokenKey, token) } export function removeToken() { return cookies.remove(TokenKey) } const LargescreenTokenKey = 'Largescreen-Token' export function getLargescreenToken() { return cookies.get(LargescreenTokenKey) } export function setLargescreenToken(token) { return cookies.set(LargescreenTokenKey, token) } export function removeLargescreenToken() { return cookies.remove(LargescreenTokenKey) }
前端调用后台接口:
import request from '@/utils/request' // 大屏用户登陆 export function largeScreenLogin(uid) { return request({ url: '/nh/auth/login', method: 'get', params:{uid:uid} }) }
小结:
1.JwtAuthenticationTokenFilter 继承OncePerRequestFilter,每一次请求都会经过此过滤器,根据请求路径过滤掉不需要鉴权的登陆路径,然后根据大屏接口路径区分不同的token 鉴权,注意此处要用:
LargeScreenAuthenticationToken largeScreenAuthenticationToken = new LargeScreenAuthenticationToken(loginLargeScreenUser,null);不然会鉴权失败。
2. 配置文件里 expireTime 此处时间必须大于零
# 大屏展示 stoken配置 stoken: # 令牌自定义标识 header: Authorization # 令牌密钥 secret: abcdefghijklmnopqrstuvwxyz # 令牌有效期(默认30分钟) expireTime: 60000000
3.LargeScreenTokenService 定义了一些生成/刷新token,获取存储对象的方法,并存储到redis。
4.ScurityConfig 里面只把 .antMatchers("/nh/auth/**").anonymous() 放开鉴权,
其他的都需要token 鉴权。
5. 前端 auth.js 里 定义两种 token :Admin-Token 和Largescreen-Token 并将其缓存到cookie ,当调用后台接口时从里面获取
request.js
import axios from 'axios' import { Notification, MessageBox, Message } from 'element-ui' import store from '@/store' import { getToken } from '@/utils/auth' import errorCode from '@/utils/errorCode' axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' // 创建axios实例 const service = axios.create({ // axios中请求配置有baseURL选项,表示请求URL公共部分 baseURL:process.env.VUE_APP_base_API, // 超时 timeout: 60000 }) // request拦截器 service.interceptors.request.use(config => { // 是否需要设置 token const isToken = (config.headers || {}).isToken === false if (getToken() && !isToken) { config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 } // get请求映射params参数 if (config.method === 'get' && config.params) { let url = config.url + '?'; for (const propName of Object.keys(config.params)) { const value = config.params[propName]; var part = encodeURIComponent(propName) + "="; if (value !== null && typeof(value) !== "undefined") { if (typeof value === 'object') { for (const key of Object.keys(value)) { let params = propName + '[' + key + ']'; var subPart = encodeURIComponent(params) + "="; url += subPart + encodeURIComponent(value[key]) + "&"; } } else { url += part + encodeURIComponent(value) + "&"; } } } url = url.slice(0, -1); config.params = {}; config.url = url; } return config }, error => { console.log(error) Promise.reject(error) }) // 响应拦截器 service.interceptors.response.use(res => { // 未设置状态码则默认成功状态 const code = res.data.code || 200; // 获取错误信息 const msg = errorCode[code] || res.data.msg || errorCode['default'] if (code === 401) { MessageBox./confirm/i('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { /confirm/iButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' } ).then(() => { store.dispatch('LogOut').then(() => { location.href = '/index'; }) }) } else if (code === 500) { Message({ message: msg, type: 'error' }) return Promise.reject(new Error(msg)) } else if (code !== 200) { Notification.error({ title: msg }) return Promise.reject('error') } else { return res.data } }, error => { console.log('err' + error) let { message } = error; if (message == "Network Error") { message = "后端接口连接异常"; } else if (message.includes("timeout")) { message = "系统接口请求超时"; } else if (message.includes("Request failed with status code")) { message = "系统接口" + message.substr(message.length - 3) + "异常"; } Message({ message: message, type: 'error', duration: 5 * 1000 }) return Promise.reject(error) } ) export default service
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)