關於前後端分離存在跨域、sessionid變動的情況討論

說明:最近公司開發一款產品,前段使用js 後端使用springboot 期間調試接口的時候會出現跨域問題,及解決之後又遇到的問題,

1:接口調試的時候遇到的問題,前段訪問我的接口,存在跨域:

表現爲:


表明存在跨域行爲;

解決:使用攔截器進行解決:

①:定義一個攔截器實現handlerInterceptor

@Component
public class CorsInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse response, Object o) throws Exception {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        response.addHeader("Access-Control-Max-Age", "3600");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}

②:設置攔截請求的路徑,這裏對所有的請求進行攔截;

@Configuration
public class MonitorInterceptor extends WebMvcConfigurerAdapter {

    private CorsInterceptor corsInterceptor;

    private LoginInterceptor loginInterceptor;

    @Autowired
    public MonitorInterceptor(CorsInterceptor corsInterceptor, LoginInterceptor loginInterceptor) {
        this.corsInterceptor = corsInterceptor;
        this.loginInterceptor = loginInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        registry.addInterceptor(corsInterceptor).addPathPatterns("/v1/**");
//        registry.addInterceptor(corsInterceptor).addPathPatterns("/v2/**");
//        registry.addInterceptor(loginInterceptor).addPathPatterns("/v1/**");
//        registry.addInterceptor(loginInterceptor).excludePathPatterns("/v2/**");
    }

通過以上方式即可實現跨域問題,但是業務中存在登錄驗證功能,也就是對於對應的功能,如果沒有登錄,不能訪問數據

這裏我還是通過攔截器進行操作的;代碼如下:

@Configuration
public class MonitorInterceptor extends WebMvcConfigurerAdapter {

    private CorsInterceptor corsInterceptor;

    private LoginInterceptor loginInterceptor;

    @Autowired
    public MonitorInterceptor(CorsInterceptor corsInterceptor, LoginInterceptor loginInterceptor) {
        this.corsInterceptor = corsInterceptor;
        this.loginInterceptor = loginInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
        registry.addInterceptor(corsInterceptor).addPathPatterns("/v1/**");
        registry.addInterceptor(corsInterceptor).addPathPatterns("/v2/**");
        registry.addInterceptor(loginInterceptor).addPathPatterns("/v1/**");//添加攔截路徑,
        registry.addInterceptor(loginInterceptor).excludePathPatterns("/v2/**");//將登錄請求的路徑釋放,即不進行攔截
    }

@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
//        httpServletResponse.setHeader("Accessx-Control-Allow-Origin", "*");
//        httpServletResponse.setHeader("Access-Control-Allow-Headers", "Authorization");

        UserDTO user = (UserDTO) httpServletRequest.getSession().getAttribute("user");
        if (user == null) {
            httpServletResponse.getOutputStream().print(BaseStatusEnums.NOT_AUTHORITY.getTag());
            return false;
        }
        return true;
    }

這裏通過驗證獲取sessio來判斷是否有該用戶,當然在登錄的時候我將用戶信息放到session中,如下:

if (userDTO != null) {
    request.getSession().setAttribute("user", userDTO);

    return new ResponseEntity<>(new BasicResult<>(true, "登錄成功", userDTO, 0), HttpStatus.OK);
}

可是;這種情況下sessionid是變化的;可通過斷點查看和前段中cookie中是否一樣



這時候出現的問題就是傳說的session跨域問題

@Component
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //添加攔截放在這裏
        httpServletResponse.setHeader("Accessx-Control-Allow-Origin", "*");
        httpServletResponse.setHeader("Access-Control-Allow-Headers", "Authorization");

        UserDTO user = (UserDTO) httpServletRequest.getSession().getAttribute("user");
        if (user == null) {
            httpServletResponse.getOutputStream().print(BaseStatusEnums.NOT_AUTHORITY.getTag());
            return false;
        }
        return true;
    }
@Configuration
public class MonitorInterceptor extends WebMvcConfigurerAdapter {

    private CorsInterceptor corsInterceptor;

    private LoginInterceptor loginInterceptor;

    @Autowired
    public MonitorInterceptor(CorsInterceptor corsInterceptor, LoginInterceptor loginInterceptor) {
        this.corsInterceptor = corsInterceptor;
        this.loginInterceptor = loginInterceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        super.addInterceptors(registry);
//這裏去掉,注意和前面對比
//        registry.addInterceptor(corsInterceptor).addPathPatterns("/v1/**");
//        registry.addInterceptor(corsInterceptor).addPathPatterns("/v2/**");
        registry.addInterceptor(loginInterceptor).addPathPatterns("/v1/**");
        registry.addInterceptor(loginInterceptor).excludePathPatterns("/v2/**");
    }

前段需要對應的操作:

$.ajax({
    url: host + $("#submitData").attr("action"),
    type: $("#submitData").attr("method"),
    data: $("#submitData").serialize(),
    dataType: "json",
//每個ajax請求都需要加上這個
    xhrFields: {
        withCredentials: true
    },
    async: isAsync,
    success: function (data) {
        sh(data);
這樣的話就解決了跨域問題,但是也存在一個問題,就是如果用戶沒有登錄去訪問頁面,頁面也會報跨域問題,如果用戶在登錄狀態去訪問,那麼就可以正常使用,不報錯誤!希望網友看到好的解決方法,能夠一起進步,歡迎留言討論








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章