百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

泰涨知识 | 请求跨域 Session不共享?你遇到过这种情形吗?

lipiwang 2024-11-03 15:51 14 浏览 0 评论

在JavaEE开发中,我们经常使用SpringMVC或SpringBoot框架进行后端开发,在传统的J2EE项目中,我们经常采用MVC的设计模式完成项目框架的搭建,那我们从MVC模式进入今天的问题。


01 / MVC模式是如何的?


MVC设计模式是经典的程序项目设计模式,M代表的是业务模型,V代表的是用户视图,C代表的是控制器,其使用MVC的设计模式目的是为了分离项目中会耦合的代码部分,让我们的后端代码各司其职,程序员只需要了解模块间的协调关系,注重业务逻辑的代码实现就可以完成后端程序的开发了。

MVC模式流程图如下:



02 / 那Session在项目中是干啥呢?


Session是服务端会话存储技术,我们在后端开发中我们会将登录用户的信息保存到session中,如果用户长时间或规定时间内没有操作,session就会过期从而让系统回到登录页面。

Session主要存储的内容:

  • 登录用户的信息作用:主页展示登录人、CURD操作携带用户鉴权
  • 系统相关信息:在多租户项目中,可能需要复杂的数据权限鉴权,也会在登录的时候携带


03 / 什么是跨域?


这个原因来自于浏览器的同源策略安全限制, 同源策略会阻止一个域的javascript脚本和另外一个域的内容进行交互。当我们使用ajax或者axios进行http访问时,非同源内容就会出现跨域请求问题。

错误图如下:



04 / 在开发中为何会跨域?


在传统的开发中,在MVC框架中,View层技术一般会使用jsp、html、freemarker、thymeleaf技术完成,但是他们的源码文件必须和项目框架文件在同一个目录下才能实现视图的解析,从而会出现耦合的效果。

从而MVVM框架出现,实现了前后端的完全分离,以vue.js为例的技术,实现前端是一个服务通过axios访问服务端,从而达到前后端物理层面的分离,但是在这种情况下就会出现不同源的情况。

vue与服务端交互:


当前端服务与后端服务不同源,但是在axios请求中会出现脚本的代理请求,就会出现非同源跨域问题。


05 / 跨域的简单判断


一个域名的组成由:协议、子域名、主域名、端口和资源地址组成;

当协议、子域名、主域名、端口号中任意一个不相同,都算作不同域,当他们相互出现请求就会“跨域”。


06 / 跨域的解决


在Vue项目中config配置文件,配置域名解析代理;

module.exports = {
  dev: {


    // Paths
    assetsSubDirectory: 'static',
    assetsPublicPath: '/',
    proxyTable: {
    '/api': {
        target:'http://localhost:8020/GDones/',
        changeOrigin:true, 
        pathRewrite:{
          '^/api': ''
        }
      }
  },


配置完成后在请求代码处,配置完整路径就通过映射路径解析即可;

axios.put("/api"+url, params,{
        headers:{'Content-Type':'application/json;charset=UTF-8'}
      })


这样我们前端的请求就再也不会跨域了,因为我们通过代理完成。


07 / 跨域解决了,那Session怎么办?


session是保存在服务器端,理论上是没有是没有限制,只要内存够大。浏览器第一次访问服务器时会创建一个session对象并返回一个JSESSIONID=ID的值,创建一个Cookie对象key为JSSIONID,value为ID的值,将这个Cookie写回浏览器,浏览器第二次访问服务器时携带Cookie信息JSESSIONID=ID的值,如果该JSESSIONID的session已经销毁,那么会重新创建一个新的session再返回一个新的JSESSIONID通过Cookie返回到浏览器针对一个web项目,一个浏览器是共享一个session,就算有两个web项目部署在同一个服务器上,针对两个项目的session是不同的。


但是在跨域的请求中,Session无法判别来自客户端的cookie和SessionID,他们每次个不相同,所服务端数据存储就得换一个思路实现,使用
Redis缓存实现。


那我们就开始吧!

安装Redis后,在服务中配置Redis相关内容,此处以Springboot为例,集成Redis缓存。


spring:
  redis:
    host: 127.0.0.1   #redis的ip,本机
    port: 6379  #redis默认端口
    password:  #默认无密码


ok,完成之后我们设计一下资源验证问题:

  • 每个客户端都有一个唯一的id描述我是一个独立的客户端;
  • 客户端id可以作为存储Redis的key,value存储客户端的用户数据;
  • 需要取出验证必须要客户端提供唯一id;

那接下来就是代码环节,以登录案例为主:


(1)登录需要验证码,验证码与客户端用户界面也是一一对应的,没有session我们就必须模拟session比较的过程,在获取验证码阶段就把客户端id对应的验证码一一对应,否则验证无法通过;

@GetMapping("/captcha")
    @ApiOperation("获取验证码图片")
    public MyResult getRegCode(HttpSession session, HttpServletResponse response,String localID){
        log.info("--- 系统操作:获取验证码");


        MyResult result = new MyResult();
        //长,宽,位数
        GifCaptcha gifCaptcha = new GifCaptcha(100, 42, 5);
        //设置类型
        gifCaptcha.setCharType(Captcha.TYPE_NUM_AND_UPPER);
        //生成验证码
        String code = gifCaptcha.text();


        log.info("--- 验证码【"+code+"】");


        //在redis中存储一套,key开头要区分一下业务
        redisUtil.set("regCode#"+localID,code);


        result.setMsg("验证码获取成功!");
        result.setData(gifCaptcha.toBase64());


        return result;
    }


(2)在登录的时候验证码的比对就可以通过登录请求中的客户端id获取验证码一一比对;

//redis获取
        String redis_regCode = (String) redisUtil.get("regCode#"+loginDto.getLocalID());



08 / 总结流程


  • 首先获取验证码发起的请求中要携带客户端唯一id;
  • 通过客户端唯一id为存储Redis的key值,value为客户端对应的验证码;
  • 在登录接口中获取客户端的唯一id,获取对应的验证码进行比较;

这样,我们就用Redis模拟了会话的方式保存验证码了。




相关推荐

前端入门——css 网格轨道详细介绍

上篇前端入门——cssGrid网格基础知识整体大概介绍了cssgrid的基本概念及使用方法,本文将介绍创建网格容器时会发生什么?以及在网格容器上使用行、列属性如何定位元素。在本文中,将介绍:...

Islands Architecture(孤岛架构)在携程新版首页的实践

一、项目背景2022,携程PC版首页终于迎来了首次改版,完成了用户体验与技术栈的全面升级。作为与用户连接的重要入口,旧版PC首页已经陪伴携程走过了22年,承担着重要使命的同时,也遇到了很多问题:维护/...

HTML中script标签中的那些属性

HTML中的<script>标签详解在HTML中,<script>标签用于包含或引用JavaScript代码,是前端开发中不可或缺的一部分。通过合理使用<scrip...

CSS 中各种居中你真的玩明白了么

页面布局中最常见的需求就是元素或者文字居中了,但是根据场景的不同,居中也有简单到复杂各种不同的实现方式,本篇就带大家一起了解下,各种场景下,该如何使用CSS实现居中前言页面布局中最常见的需求就是元...

CSS样式更改——列表、表格和轮廓

上篇文章主要介绍了CSS样式更改篇中的字体设置Font&边框Border设置,这篇文章分享列表、表格和轮廓,一起来看看吧。1.列表List1).列表的类型<ulstyle='list-...

一文吃透 CSS Flex 布局

原文链接:一文吃透CSSFlex布局教学游戏这里有两个小游戏,可用来练习flex布局。塔防游戏送小青蛙回家Flexbox概述Flexbox布局也叫Flex布局,弹性盒子布局。它决定了...

css实现多行文本的展开收起

背景在我们写需求时可能会遇到类似于这样的多行文本展开与收起的场景:那么,如何通过纯css实现这样的效果呢?实现的难点(1)位于多行文本右下角的展开收起按钮。(2)展开和收起两种状态的切换。(3)文本...

css 垂直居中的几种实现方式

前言设计是带有主观色彩的,同样网页设计中的css一样让人摸不头脑。网上列举的实现方式一大把,或许在这里你都看到过,但既然来到这里我希望这篇能让你看有所收获,毕竟这也是前端面试的基础。实现方式备注:...

WordPress固定链接设置

WordPress设置里的最后一项就是固定链接设置,固定链接设置是决定WordPress文章及静态页面URL的重要步骤,从站点的SEO角度来讲也是。固定链接设置决定网站URL,当页面数少的时候,可以一...

面试发愁!吃透 20 道 CSS 核心题,大厂 Offer 轻松拿

前端小伙伴们,是不是一想到面试里的CSS布局题就发愁?写代码时布局总是对不齐,面试官追问兼容性就卡壳,想跳槽却总被“多列等高”“响应式布局”这些问题难住——别担心!从今天起,咱们每天拆解一...

3种CSS清除浮动的方法

今天这篇文章给大家介绍3种CSS清除浮动的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。首先,这里就不讲为什么我们要清楚浮动,反正不清除浮动事多多。下面我就讲3种常用清除浮动的...

2025 年 CSS 终于要支持强大的自定义函数了?

大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!1.什么是CSS自定义属性CSS自...

css3属性(transform)的一个css3动画小应用

闲言碎语不多讲,咱们说说css3的transform属性:先上效果:效果说明:当鼠标移到a标签的时候,从右上角滑出二维码。实现方法:HTML代码如下:需要说明的一点是,a链接的跳转需要用javasc...

CSS基础知识(七)CSS背景

一、CSS背景属性1.背景颜色(background-color)属性值:transparent(透明的)或color(颜色)2.背景图片(background-image)属性值:none(没有)...

CSS 水平居中方式二

<divid="parent"><!--定义子级元素--><divid="child">居中布局</div>...

取消回复欢迎 发表评论: