Hello大家好,本章我們處理前後端分離開發時出現的問題 。有問題可以聯絡我mr_beany@163.com。另求各路大神指點,感謝
隨著技術不斷髮展,現在越來越多的專案開始前後端分離方式進行開發。在傳統專案中,shiro登陸成功自動儲存sessionId到cookie中,後臺根據sessionid獲取當前登陸角色資訊。在前後端分離的專案中,由於ip,埠不一致的原因,導致無法請求後端介面(跨域)和無法在cookie中獲取sessionId。本章處理以上兩個問題。
一:處理跨域問題
我這裡的前端專案啟用的是8800埠,後臺啟用的是8080埠,由於埠不一致導致在前端通過axios請求時出現如下錯誤
解決方案:
開啟core→configuer→WebConfigurer.java
新增如下程式碼:
private CorsConfiguration buildConfig() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
//請求方法 config.addAllowedMethod(HttpMethod.GET);
config.addAllowedMethod(HttpMethod.POST);
config.addAllowedMethod(HttpMethod.PUT);
config.addAllowedMethod(HttpMethod.DELETE);
config.addAllowedMethod(HttpMethod.OPTIONS);
return config;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
//處理全部請求路徑
configSource.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(configSource);
}複製程式碼
再次請求:
請求成功,拿到資料。(忽略辣眼睛的頁面)
二:處理Shiro獲取SessionId
shiro原邏輯是在cookie中獲取sessionId,這裡我們修改一下其中的邏輯。
- 在登陸成功時將sessionid返回到前臺,然後每次請求時在請求頭中攜帶sessionid。
- 重寫shiro獲取sessionid方法。
登陸方法:
@Override
public Map<String, Object> userLogin(String userName, String password) {
Subject currentUser = SecurityUtils.getSubject();
currentUser.login(new UsernamePasswordToken(userName, password));
//從session取出使用者資訊
//UserInfo user = (UserInfo) currentUser.getPrincipal();
Map<String,Object> map = new HashMap<>(3);
map.put("sessionId",currentUser.getSession().getId());
return map;
}複製程式碼
重寫shiro獲取sessionid
新建core→shiro→MySessionManager.java
package com.example.demo.core.shiro;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.Serializable;
/**
* @author zy
*/
public class MySessionManager extends DefaultWebSessionManager {
//請求頭的名字
private static final String AUTHORIZATION = "Authorization";
private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
public MySessionManager() {
super();
}
@Override
protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
//如果請求頭中有 Authorization 則其值為sessionId
if (!StringUtils.isEmpty(id)) {
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
return id;
} else {
//否則按預設規則從cookie取sessionId
return super.getSessionId(request, response);
}
}
}複製程式碼
修改core→configuer→ShiroConfigurer.java
新增如下程式碼:
@Bean
public SessionManager sessionManager(){
return new MySessionManager();
}複製程式碼
以上,可以解決文章開篇提出的兩個問題。
專案地址
碼雲地址: gitee.com/beany/mySpr…
GitHub地址: github.com/MyBeany/myS…
寫文章不易,如對您有幫助,請幫忙點下star