0°

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

Hello大家好,本章我们处理前后端分离开发时出现的问题 。有问题可以联系我mr_beany@163.com。另求各路大神指点,感谢

随着技术不断发展,现在越来越多的项目开始前后端分离方式进行开发。在传统项目中,shiro登陆成功自动保存sessionId到cookie中,后台根据sessionid获取当前登陆角色信息。在前后端分离的项目中,由于ip,端口不一致的原因,导致无法请求后端接口(跨域)和无法在cookie中获取sessionId。本章处理以上两个问题。

一:处理跨域问题

我这里的前端项目启用的是8800端口,后台启用的是8080端口,由于端口不一致导致在前端通过axios请求时出现如下错误

解决方案:

打开core→configuer→WebConfigurer.java

添加如下代码:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
1private CorsConfiguration buildConfig() {
2    CorsConfiguration config = new CorsConfiguration();    
3    config.addAllowedOrigin("*");    
4    config.addAllowedHeader("*");    
5    //请求方法    config.addAllowedMethod(HttpMethod.GET);    
6    config.addAllowedMethod(HttpMethod.POST);    
7    config.addAllowedMethod(HttpMethod.PUT);    
8    config.addAllowedMethod(HttpMethod.DELETE);    
9    config.addAllowedMethod(HttpMethod.OPTIONS);    
10    return config;
11}
12
13@Bean
14public CorsFilter corsFilter() {
15    UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
16    //处理全部请求路径
17    configSource.registerCorsConfiguration("/**", buildConfig());
18    return new CorsFilter(configSource);
19}复制代码
20

再次请求:

请求成功,拿到数据。(忽略辣眼睛的页面)

二:处理Shiro获取SessionId

shiro原逻辑是在cookie中获取sessionId,这里我们修改一下其中的逻辑。

  • 在登陆成功时将sessionid返回到前台,然后每次请求时在请求头中携带sessionid。
  • 重写shiro获取sessionid方法。

登陆方法:


1
2
3
4
5
6
7
8
9
10
11
1@Override
2public Map<String, Object> userLogin(String userName, String password) {
3    Subject currentUser = SecurityUtils.getSubject();
4    currentUser.login(new UsernamePasswordToken(userName, password));
5    //从session取出用户信息
6    //UserInfo user = (UserInfo) currentUser.getPrincipal();  
7    Map<String,Object> map = new HashMap<>(3);
8    map.put("sessionId",currentUser.getSession().getId());
9    return map;
10}复制代码
11

重写shiro获取sessionid

新建core→shiro→MySessionManager.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
1package com.example.demo.core.shiro;
2
3import org.apache.commons.lang3.StringUtils;
4import org.apache.shiro.web.servlet.ShiroHttpServletRequest;
5import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
6import org.apache.shiro.web.util.WebUtils;
7
8import javax.servlet.ServletRequest;
9import javax.servlet.ServletResponse;
10import java.io.Serializable;
11
12/**
13 * @author zy
14 */
15public class MySessionManager extends DefaultWebSessionManager {
16
17    //请求头的名字
18    private static final String AUTHORIZATION = "Authorization";
19
20    private static final String REFERENCED_SESSION_ID_SOURCE = "Stateless request";
21
22    public MySessionManager() {
23        super();
24    }
25
26    @Override
27    protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
28        String id = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
29        //如果请求头中有 Authorization 则其值为sessionId
30        if (!StringUtils.isEmpty(id)) {
31            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, REFERENCED_SESSION_ID_SOURCE);
32            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, id);
33            request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
34            return id;
35        } else {
36            //否则按默认规则从cookie取sessionId
37            return super.getSessionId(request, response);
38        }
39    }
40}复制代码
41

修改core→configuer→ShiroConfigurer.java

添加如下代码:


1
2
3
4
5
1@Bean
2public SessionManager sessionManager(){
3    return new MySessionManager();
4}复制代码
5

以上,可以解决文章开篇提出的两个问题。

项目地址

码云地址: gitee.com/beany/mySpr…

GitHub地址: github.com/MyBeany/myS…

写文章不易,如对您有帮助,请帮忙点下star

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!