從零搭建自己的SpringBoot後臺框架(二十三)

Mr_初晨發表於2019-02-13
Hello大家好,本章我們處理前後端分離開發時出現的問題 。有問題可以聯絡我mr_beany@163.com。另求各路大神指點,感謝

隨著技術不斷髮展,現在越來越多的專案開始前後端分離方式進行開發。在傳統專案中,shiro登陸成功自動儲存sessionId到cookie中,後臺根據sessionid獲取當前登陸角色資訊。在前後端分離的專案中,由於ip,埠不一致的原因,導致無法請求後端介面(跨域)和無法在cookie中獲取sessionId。本章處理以上兩個問題。

一:處理跨域問題

我這裡的前端專案啟用的是8800埠,後臺啟用的是8080埠,由於埠不一致導致在前端通過axios請求時出現如下錯誤

從零搭建自己的SpringBoot後臺框架(二十三)

解決方案:

開啟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);
}複製程式碼

再次請求:

從零搭建自己的SpringBoot後臺框架(二十三)

請求成功,拿到資料。(忽略辣眼睛的頁面)

二:處理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從零搭建自己的SpringBoot後臺框架(二十三)


相關文章