21.Shiro在springboot与vue前后端分离项目里的session管理

https://blog.csdn.net/weixin_34248849/article/details/92632851

1.前言

当决定前端与后端代码分开部署时,发现shiro自带的session不起作用了。

然后通过对请求head的分析,然后在网上查找一部分解决方案。

最终就是,登录成功之后,前端接收到后端传回来的sessionId,存入cookie当中。

之后,前端向后端发送请求时,请求Head中都会带上这个sessionid。

后端代码通过对这个sessionid的解析,拿到正确的session。

2.代码改造

(1)后端代码改造

  1. 添加CustomSessionManager.java

    
        
        
    1. /**
    2. * 类的详细说明
    3. *
    4. * @author 郭广明
    5. * @version 1.0
    6. * @Date 2018/11/3014:56
    7. */
    8. public class CustomSessionManager extends DefaultWebSessionManager {
    9. /**
    10. * 获取请求头中key为“Authorization”的value == sessionId
    11. */
    12. private static final String AUTHORIZATION ="Authorization";
    13. private static final String REFERENCED_SESSION_ID_SOURCE = "cookie";
    14. /**
    15. * @Description shiro框架 自定义session获取方式<br/>
    16. * 可自定义session获取规则。这里采用ajax请求头 {@link AUTHORIZATION}携带sessionId的方式
    17. */
    18. @Override
    19. protected Serializable getSessionId(ServletRequest request, ServletResponse response) {
    20. // TODO Auto-generated method stub
    21. String sessionId = WebUtils.toHttp(request).getHeader(AUTHORIZATION);
    22. if (StringUtils.isNotEmpty(sessionId)) {
    23. request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_SOURCE, ShiroHttpServletRequest.COOKIE_SESSION_ID_SOURCE);
    24. request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID, sessionId);
    25. request.setAttribute(ShiroHttpServletRequest.REFERENCED_SESSION_ID_IS_VALID, Boolean.TRUE);
    26. return sessionId;
    27. }
    28. return super.getSessionId(request, response);
    29. }
    30. }
  2. 改造ShiroConfig.java

    
        
        
    1. @Configuration
    2. public class ShiroConfig {
    3. @Autowired
    4. private UserService userService;
    5. @Bean
    6. public ShiroFilterFactoryBean shirFilter(SecurityManager securityManager) {
    7. ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
    8. // 必须设置 SecurityManager
    9. shiroFilterFactoryBean.setSecurityManager(securityManager);
    10. // 如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
    11. shiroFilterFactoryBean.setLoginUrl("/login");
    12. // 拦截器.
    13. Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>();
    14. // 配置不会被拦截的链接 顺序判断
    15. filterChainDefinitionMap.put("/static/**", "anon");
    16. filterChainDefinitionMap.put("/doLogin", "anon");
    17. filterChainDefinitionMap.put("/swagger-resources", "anon");
    18. filterChainDefinitionMap.put("/v2/api-docs", "anon");
    19. filterChainDefinitionMap.put("/webjars/**", "anon");
    20. filterChainDefinitionMap.put("/swagger-ui.html", "anon");
    21. // <!-- 过滤链定义,从上向下顺序执行,一般将 /**放在最为下边 -->:这是一个坑呢,一不小心代码就不好使了;
    22. // <!-- authc:所有url都必须认证通过才可以访问; anon:所有url都都可以匿名访问-->
    23. filterChainDefinitionMap.put("/**", "anon");
    24. shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
    25. System.out.println("Shiro拦截器工厂类注入成功");
    26. return shiroFilterFactoryBean;
    27. }
    28. /**
    29. * 注入MyRealm
    30. * @return
    31. */
    32. @Bean
    33. public SecurityManager securityManager() {
    34. DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
    35. // 设置realm.
    36. securityManager.setSessionManager(sessionManager());
    37. securityManager.setRealm(myShiroRealm());
    38. return securityManager;
    39. }
    40. /**
    41. * 配置注解
    42. * @param securityManager
    43. * @return
    44. */
    45. @Bean
    46. public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) {
    47. AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor
    48. = new AuthorizationAttributeSourceAdvisor();
    49. authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
    50. return authorizationAttributeSourceAdvisor;
    51. }
    52. @Bean
    53. public MyRealm myShiroRealm() {
    54. return new MyRealm(userService);
    55. }
    56. @Bean("sessionManager")
    57. public SessionManager sessionManager(){
    58. CustomSessionManager manager = new CustomSessionManager();
    59. /*使用了shiro自带缓存,
    60. 如果设置 redis为缓存需要重写CacheManager(其中需要重写Cache)
    61. manager.setCacheManager(this.RedisCacheManager());*/
    62. manager.setSessionDAO(new EnterpriseCacheSessionDAO());
    63. return manager;
    64. }
    65. }

(2)前端代码改造

  1. 添加CookieUtil.js

    
        
        
    1. export default {
    2. setCookie: (name,value,days) =>{
    3. var d = new Date;
    4. d.setTime(d.getTime() + 24*60*60*1000*days);
    5. window.document.cookie = name + "=" + value + ";path=/;expires=" + d.toGMTString();
    6. },
    7. getCookie: name =>{
    8. var v = window.document.cookie.match('(^|;) ?' + name + '=([^;]*)(;|$)');
    9. return v ? v[2] : null;
    10. },
    11. delCookie: name =>{
    12. this.setCookie(name, '', -1); //将时间设置为过去时,立即删除cookie
    13. }
    14. }
  2. 改造HttpUtil.js

    
        
        
    1. import axios from 'axios'
    2. import doCookie from '@/util/cookieUtil'
    3. axios.defaults.headers.common['Authorization'] = doCookie.getCookie("SESSIONID")
    4. axios.defaults.baseURL = 'http://127.0.0.1:8080'
    5. /**
    6. * Get请求
    7. */
    8. export function get(url, callback){
    9. axios.get(url)
    10. .then(function (response) {
    11. if(response.data.length==0 || response.data==null) {
    12. callback(null,true)
    13. } else {
    14. callback(response.data,true)
    15. }
    16. })
    17. .catch(function (error) {
    18. callback(null,false)
    19. })
    20. }
    21. export function remove(url, callback){
    22. axios.delete(url)
    23. .then(function (response) {
    24. if(response.data.length==0 || response.data==null) {
    25. callback(null,true)
    26. } else {
    27. callback(response.data,true)
    28. }
    29. })
    30. .catch(function (error) {
    31. callback(null,false)
    32. })
    33. }
    34. export function post(url, data, callback){
    35. axios.post(url,data)
    36. .then(function (response) {
    37. if(response.data.length==0 || response.data==null) {
    38. callback(null,true)
    39. } else {
    40. callback(response.data,true)
    41. }
    42. })
    43. .catch(function (error) {
    44. callback(null,false)
    45. })
    46. }
    47. export function put(url, data, callback){
    48. axios.put(url,data)
    49. .then(function (response) {
    50. if(response.data.length==0 || response.data==null) {
    51. callback(null,true)
    52. } else {
    53. callback(response.data,true)
    54. }
    55. })
    56. .catch(function (error) {
    57. callback(null,false)
    58. })
    59. }
    60. export default {
    61. get,
    62. post,
    63. put,
    64. remove,
    65. }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值