VUE+SpringCloud 跨域+Session管理解決辦法
阿新 • • 發佈:2019-01-05
近期在做一個商城時,採用前後端分離開發,前端用vue,後臺用SpringCloud微服務。業務流程為,商城前端通過跨域請求微服務閘道器(Zuul叢集),由閘道器路由到各個微服務節點。 遇到的問題:1.請求跨域,2.Session 需要共享,問題大家都知道,不多講,直接上解決辦法。 解決辦法:一.前端: 在Zuul閘道器建立一個post型別的過濾器,增加以下程式碼: (2)增加HttpSession全域性配置:
http://192.168.10.10:10022/userinfo/** ==> http://192.168.10.221:9980/ (Zuul叢集閘道器)http://192.168.10.10:10022/開頭的其他請求都轉發至http://192.168.10.10:10020/(前端商城)以上配置完成,即可實現同源訪問。商城地址為:http://192.168.10.10:10020/ 後臺閘道器的IP和埠也為http://192.168.10.10:10020/第二種方案能徹底解決跨域問題,但是開發階段,不適合本地除錯,所以建議兩種方案結合使用,這樣既支援本地PC除錯,也可保證生產環境全面支援安卓和IOS系統。
前端都採用POST方法請求後臺,在main.js中增加一個攔截器
Vue.http.options.emulateJSON = false;
// Vue.http.options.emulateJSON = true;
Vue.http.options.xhr = { withCredentials: true };
Vue.http.interceptors.push((request, next) => {
request.credentials = true
next()
});
目的是攔截每一個post請求,設定withCredentials: true屬性,以便客戶端請求強行上送Cookie資訊。二.後臺閘道器1.跨域問題
2.Seesion管理微服務Seesion管理採用HttpSession。(1)pom.xml 增加依賴RequestContext context = RequestContext.getCurrentContext(); HttpServletRequest request = context.getRequest(); String origin = request.getHeader("Origin"); if(origin == null) { origin = request.getHeader("Referer"); } context.addZuulResponseHeader("Content-Type","application/x-www-form-urlencoded"); context.addZuulResponseHeader("Access-Control-Allow-Origin",origin); context.addZuulResponseHeader("Access-Control-Allow-Credentials","true");
<!-- spring session --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> </dependency> <!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> <version>1.4.7.RELEASE</version> </dependency>
@EnableRedisHttpSession
public class HttpSessionConfig {
@Bean
public JedisConnectionFactory connectionFactory() {
JedisConnectionFactory connection = new JedisConnectionFactory();
connection.setHostName("192.168.10.10");
connection.setPort(6379);
return connection;
}
}
(3)應用:在Zuul pre型別的過濾器中校驗使用者登入狀態 RequestContext context = RequestContext.getCurrentContext();
HttpSession session = request.getSession();
UserInfo userInfo = (UserInfo) session.getAttribute("userInfo");
if(userInfo==null){
// 需要校驗登入狀態
context.setSendZuulResponse(false);
context.setResponseStatusCode(200);
Iresp_common iresp_common = new Iresp_common("2000","尚未登入");
context.setResponseBody(gson.toJson(iresp_common));
return null;
}
以上解決方案只針對安卓瀏覽器,和PC電腦瀏覽器。由於蘋果手機版safari和MAC版Safari預設是阻止向第三方網站請求Cookie資訊的,所以程式層面的跨域解決方案無法繞過IOS系統瀏覽器。如需相容IOS系統,本人想到的辦法是用nginx做代理,人為使前後端處於同一IP,埠環境下,騙過瀏覽器,這樣就不存在跨域問題了。具體辦法如下:通過nginx進行路由配置,凡是http://192.168.10.10:10022/userinfo/**型別的請求全部轉發至http://192.168.10.221:9980/ (Zuul叢集閘道器),以此類推完成如下配置(因目前微服務拆分了四個服務,所以只需配置四條資訊)http://192.168.10.10:10022/userinfo/** ==> http://192.168.10.221:9980/ (Zuul叢集閘道器)http://192.168.10.10:10022/開頭的其他請求都轉發至http://192.168.10.10:10020/(前端商城)以上配置完成,即可實現同源訪問。商城地址為:http://192.168.10.10:10020/ 後臺閘道器的IP和埠也為http://192.168.10.10:10020/第二種方案能徹底解決跨域問題,但是開發階段,不適合本地除錯,所以建議兩種方案結合使用,這樣既支援本地PC除錯,也可保證生產環境全面支援安卓和IOS系統。