從零搭建本身的SpringBoot後臺框架(二十三)

Hello你們好,本章咱們處理先後端分離開發時出現的問題 。有問題能夠聯繫我mr_beany@163.com。另求各路大神指點,感謝

隨着技術不斷髮展,如今愈來愈多的項目開始先後端分離方式進行開發。在傳統項目中,shiro登錄成功自動保存sessionId到cookie中,後臺根據sessionid獲取當前登錄角色信息。在先後端分離的項目中,因爲ip,端口不一致的緣由,致使沒法請求後端接口(跨域)和沒法在cookie中獲取sessionId。本章處理以上兩個問題。前端

一:處理跨域問題

我這裏的前端項目啓用的是8800端口,後臺啓用的是8080端口,因爲端口不一致致使在前端經過axios請求時出現以下錯誤java


解決方案:ios

打開core→configuer→WebConfigurer.javagit

添加以下代碼:github

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);
}複製代碼

再次請求:web


請求成功,拿到數據。(忽略辣眼睛的頁面)apache

二:處理Shiro獲取SessionId

shiro原邏輯是在cookie中獲取sessionId,這裏咱們修改一下其中的邏輯。axios

  • 在登錄成功時將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

相關文章
相關標籤/搜索