色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

Springboot前后端分離項目配置跨域?qū)崿F(xiàn)過程解析

瀏覽:3日期:2023-05-03 15:10:26

項目登錄流程如下

用戶進(jìn)入前端登錄界面,輸入賬號密碼等,輸入完成之后前端發(fā)送請求到后端(攔截器不會攔截登錄請求),后端驗證賬號密碼等成功之后生成Token并存儲到數(shù)據(jù)庫,數(shù)據(jù)庫中包含該Token過期時間,然后返回生成的Token到前端。

前端收到Token,表示登錄成功,把這個Token存儲本地。然后跳轉(zhuǎn)到用戶中心頁面,用戶中心頁面在ajax的請求頭中帶上Token,跟隨請求用戶數(shù)據(jù)接口一起帶到后端。

后端通過攔截器攔截到這個請求,去判斷這個Token是否有效,有效就放過去做他該做的事情,無效就拋出異常。

跨域配置

先說一下這個前后分離的項目,已經(jīng)配置過跨域這些問題。我這里后端WebMvcConfig配置的方式如下:

import com.zdyl.devicemanagement.interceptor.AccessInterceptor;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;import org.springframework.web.servlet.config.annotation.CorsRegistry;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import javax.annotation.Resource;import java.util.ArrayList;import java.util.List;@Configurationpublic class WebMvcConfig implements WebMvcConfigurer { @Resource private WebServerConfig webServerConfig; @Bean public AccessInterceptor getAccessInterceptor() { return new AccessInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { List<String> excludeUrl = new ArrayList<>(); excludeUrl.add('/error'); excludeUrl.add('/v1/zdyl/downloadFile'); excludeUrl.add('/v1/zdyl/lcoStation/qrcode/**'); excludeUrl.add('/devicemanagement/images/**/*'); excludeUrl.add('/upgrade/**'); excludeUrl.add('/v1/zdyl/login/**'); excludeUrl.add('/NewsImage/**'); excludeUrl.add('/v1/zdyl/equipment/alarm/toExcel/test'); excludeUrl.add('/v1/zdyl/deviceMonitoring/get/alarm/toExcel/**'); registry.addInterceptor(getAccessInterceptor()).addPathPatterns('/**').excludePathPatterns(excludeUrl); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { List<String> locations = new ArrayList<String>(); locations.add('classpath:/META-INF/resources/'); locations.add('classpath:/resources/'); locations.add('classpath:/public/'); locations.add('file:' + webServerConfig.getUploadFileLocation()); locations.add('file:' + webServerConfig.getPicpath()); locations.add('file:' + webServerConfig.getProjectsource()); String[] myArray = new String[locations.size()]; registry.addResourceHandler('/**').addResourceLocations(locations.toArray(myArray)); } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin('*'); config.addAllowedHeader('*'); config.addAllowedMethod('*'); source.registerCorsConfiguration('/**', config); return new CorsFilter(source); } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping('/**').allowedHeaders('*').allowCredentials(true).allowedOrigins('*').allowedMethods('POST', 'GET', 'DELETE', 'PUT', 'OPTIONS').maxAge(3600); }}

前端每次發(fā)送請求也都有在ajax里面設(shè)置xhrFields:{withCredentials: true}屬性。

攔截器代碼

import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.core.toolkit.StringUtils;import com.zdyl.devicemanagement.common.exception.RRException;import com.zdyl.devicemanagement.common.utils.AccountNumber;import com.zdyl.devicemanagement.common.utils.RedisSavePrefix;import com.zdyl.devicemanagement.common.utils.RedisUtils;import com.zdyl.devicemanagement.common.utils.SystemConstants;import com.zdyl.devicemanagement.entity.LcoUsers;import com.zdyl.devicemanagement.entity.Login;import com.zdyl.devicemanagement.service.LcoUsersService;import lombok.extern.slf4j.Slf4j;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.Date;@Slf4jpublic class AccessInterceptor extends HandlerInterceptorAdapter { @Resource private RedisUtils redisUtils; @Resource private LcoUsersService lcoUsersService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info('------------------------AccessInterceptor-------------------------'); if (request.getMethod().equals(RequestMethod.OPTIONS.name())) { return super.preHandle(request, response, handler); } //獲取請求token,如果token不存在,直接返回401 String token = getRequestToken(request); String loginId = getRequestloginId(request); if (StringUtils.isEmpty(token)) { throw new RRException('token為空', 401); } if (StringUtils.isEmpty(loginId)) { throw new RRException('loginId為空', 401); } Object users = redisUtils.getObject(redisUtils.getKey(RedisSavePrefix.Login, loginId), AccountNumber.loginDataBase); if (users == null) { throw new RRException('用戶尚未登錄', 401); } Login loginUser = JSONObject.parseObject(JSON.toJSONString(users), Login.class); if (!loginUser.getToken().equals(token)) { throw new RRException('token不匹配', 401); } Date loginTime = loginUser.getLoginTime(); long exitTime = loginTime.getTime() / 1000 + 7200; long time = new Date().getTime(); long nowTime = new Date().getTime() / 1000; if (nowTime > exitTime) { throw new RRException('token已過期!', 401); } QueryWrapper<LcoUsers> lcoUsersQueryWrapper = new QueryWrapper<>(); lcoUsersQueryWrapper.eq('phone', loginUser.getLoginID()); LcoUsers lcoUsers = lcoUsersService.getOne(lcoUsersQueryWrapper); request.setAttribute(SystemConstants.CURRENTUSER, lcoUsers); return super.preHandle(request, response, handler); } /** * 獲取請求的token */ private String getRequestToken(HttpServletRequest httpRequest) { //從header中獲取token String host = httpRequest.getHeader('token'); //如果header中不存在token,則從參數(shù)中獲取token if (StringUtils.isEmpty(host)) { host = httpRequest.getParameter('token'); }// if (StringUtils.isEmpty(host)) {// Cookie[] cks = httpRequest.getCookies();// for (Cookie cookie : cks) {//if (cookie.getName().equals('yzjjwt')) {// host = cookie.getValue();// return host;//}// }// } return host; } /** * 獲取請求的loginId */ private String getRequestloginId(HttpServletRequest httpRequest) { //從header中獲取token String loginId = httpRequest.getHeader('loginId'); //如果header中不存在token,則從參數(shù)中獲取token if (StringUtils.isEmpty(loginId)) { loginId = httpRequest.getParameter('loginId'); }// if (StringUtils.isEmpty(loginId)) {// Cookie[] cks = httpRequest.getCookies();// for (Cookie cookie : cks) {//if (cookie.getName().equals('yzjjwt')) {// loginId = cookie.getValue();// return loginId;//}// }// } return loginId; }/** * 對跨域提供支持 */protected boolean addCors(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setHeader('Access-control-Allow-Origin', httpServletRequest.getHeader('Origin')); httpServletResponse.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,PUT,DELETE'); httpServletResponse.setHeader('Access-Control-Allow-Headers', httpServletRequest.getHeader('Access-Control-Request-Headers')); // 跨域時會首先發(fā)送一個option請求,這里我們給option請求直接返回正常狀態(tài) if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) { httpServletResponse.setStatus(HttpStatus.OK.value()); return false; } return super.preHandle(request, response);}}

自定義異常RRException代碼

/** * 自定義異常 */public class RRException extends RuntimeException { private static final long serialVersionUID = 1L; private String message; private String code = 'INVALID'; private int status = 0; public RRException(String msg) { super(msg); this.message = msg; } public RRException(String msg, Throwable e) { super(msg, e); this.message = msg; } public RRException(String msg, String code) { super(msg); this.message = msg; this.code = code; } public RRException(String msg, int status) { super(msg); this.message = msg; this.status = status; } public RRException(String msg, String code, Throwable e) { super(msg, e); this.message = msg; this.code = code; } public String getMsg() { return message; } public void setMsg(String msg) { this.message = msg; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public int getStatus() { return status; } public void setStatus(int status) { this.status = status; }}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 日本一区二区三区精品视频 | 国产精品无码久久久久 | 免费公开视频人人人人人人人 | 91精品国产爱久久久久 | 国产日韩欧美一区二区三区综合 | 免费观看性欧美大片无片 | 日本二级毛片免费 | 亚洲男人天堂2018 | 日韩欧美国产视频 | 欧美一级专区免费大片野外交 | 亚洲欧美日韩中文字幕在线一 | 欧美 亚洲 另类 自拍 在线 | 国产精品亚洲综合久久 | 久久精品视频在线观看榴莲视频 | 日韩 欧美 自拍 在线 视频 | 中文字幕一区二区在线观看 | 国产成人免费不卡在线观看 | 国产精品一级片 | 国产成人亚洲综合欧美一部 | 国产a视频| 亚洲欧洲视频在线 | 91久久精品视频 | 成人精品综合免费视频 | 一区二区三区四区视频 | 亚洲精品专区一区二区欧美 | 精品国产一区二区三区不卡蜜臂 | www亚洲免费| 亚洲刺激视频 | 欧美成人高清手机在线视频 | 精品国产成人a区在线观看 精品国产成人a在线观看 | 日韩国产在线观看 | 18视频免费网址在线观看 | 一级一片一a一片 | 亚洲高清在线观看 | 亚洲国产欧美国产综合一区 | 美女擦逼 | 亚洲成a人片 | 精品一区二区三区免费毛片爱 | 黄色美女网站免费 | 成人免费网址在线 | 三级在线国产 |