从零搭建自己的SpringBoot后台框架(二十三)

3,076 阅读2分钟
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