from my typora

MZY项目笔记:session歧路

以前对session的理解不够透彻,今天跪着来补。

前因是因为项目问题:

在浏览器中,一个浏览器多次请求默认状态下只会有一个sessionId,但是当两边都是服务端的时候,每次重复请求,此时会被服务端当成不同的请求来处理!

前后台分离之后,前后台运行在不同的容器上,每次前端请求都会被后台认为是一次新的会话,在后台输出当前的sessionId发现,每次的sessionId都不一样,所以这种情况下没法做登录和数据接口的权限过滤操作。

那该怎么办?

开始了漫长的尝试歧路。

1. 手动加上cookie的header。

在第一次登录的时候,服务端把sessionId带给前端,前端把sesionId存到一个变量中。

在之后ajax的时候,提前加上cookie的header,把sessionId手动传上去,这样是不是就能让服务器识别,找到对应的会话了?

$.ajax({
xhrFields: {
withCredentials: true
},
type: "GET",
url:"http://localhost:8080/getData",
beforeSend: function(request) {
// request.setRequestHeader("JSESSIONID", JSESSIONID);
// request.setRequestHeader("Set-Cookie", JSESSIONID);
request.setRequestHeader("Cookie", "JSESSIONID="+JSESSIONID);
},
dataType:"json",
success: function(msg) {
console.log(msg);
}
});

400、bad request


以上都是不行的,在w3c的标准中直接就不允许:

以下转自的噢可爱滴蓝晶晶的CSDN:

w3c规定,当请求的header匹配以下不安全字符时,将被终止

Accept-Charset
Accept-Encoding
Connection
Content-Length
Cookie
Cookie2
Content-Transfer-Encoding
Date
Expect
Host
Keep-Alive
Referer
TE
Trailer
Transfer-Encoding
Upgrade
User-Agent
Via

2.自己模拟一个SessionContext。

在的SIHAIloveYAN的CSDN上看到了模拟session容器的文章:

// 以下是我的SpringBoot中的测试:

// 创建一个自己的SessionContext
package club.mzywucai.cros_session_model.domain; import org.springframework.stereotype.Component; import javax.servlet.http.HttpSession;
import java.util.HashMap; /**
* @author mzywucai
* @Description
* @date 2018/12/10
*/
public class SessionContext { private static HashMap sessionMap = new HashMap(); public static synchronized void AddSession(HttpSession session) {
if (session != null) {
sessionMap.put(session.getId(), session);
}
} public static synchronized void DelSession(HttpSession session) {
if (session != null) {
sessionMap.remove(session.getId());
}
} public static synchronized HttpSession getSession(String session_id) {
if (session_id == null)
return null;
return (HttpSession) sessionMap.get(session_id);
}
} // 创建一个监听器,每次session创建就add,session销毁就remove,防止内存泄漏
package club.mzywucai.cros_session_model.listener; import club.mzywucai.cros_session_model.domain.SessionContext; import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener; /**
* @author mzywucai
* @Description
* @date 2018/12/10
*/
@WebListener
public class SessionListener implements HttpSessionListener { public void sessionCreated(HttpSessionEvent httpSessionEvent) {
SessionContext.AddSession(httpSessionEvent.getSession());
} public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
HttpSession session = httpSessionEvent.getSession();
SessionContext.DelSession(session);
}
}

但是这样就能解决了吗?现在前端访问后台我就能把session对应起来了吗?

如果我多次请求的话,多个session不就在内存里面炸了?我新请求一次,create一个session;虽然我从context中拿到了想要的session,但是同时岂不是也压入了很多没用的session?

原来servlet中的session不一定会被创建,我居然今天才知道。

就在我想这个问题的时候,我得知了一个惊天的大秘密!(所以我就加粗斜体写了)

原来,只要我们不注入session就不会创建session!!!

回想起最初学servlet的时候,通过request拿到session的时候,是通过request.getSession(),getSession中有个boolean类型的参数:

getSession(true):

​ 当内存中不存在session的时候就创建session。

getSession(false):

​ 当内存中不存在session的时候就拿不到session(故此时的会话并不会创建session);

session的使用,其实是建立在一种假设用户回访才会使用的!!

果然知识需要回顾,不然这种简单的都会忘记

3.引入token机制

得到启发的帖子

这下大问题就真的没有了,我只在登录的时候,创建一个session,把登录的sessionId和一些关键信息加密组合作为token给前台并放入我的SessionContext中,后面的每次会话都是取现有的session,都不会再进行session的创建动作了(注意不要再在其它地方随便创建session了,因为前后台分离造成每次请求都是一次新的会话,会造成内存泄漏)!

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>token测试</title> </head>
<script src="js/jQuery_3.3.1.js"></script>
<script type="text/javascript">
var token;
$(document).ready(function(){
$("#getData").click(function(){
alert("click"); $.ajax({
type: "GET",
url:"http://localhost:8080/getData",
beforeSend: function(request) {
request.setRequestHeader("Authorization", token);
console.log(token);
},
dataType:"json",
success: function(msg) {
console.log(msg);
}
});
}); $.ajax({
type: "POST",
url:"http://localhost:8080/login",
data: "username=mzy&password=123",
dataType:"json",
success: function(msg) {
JSESSIONID = msg.data;
if (msg.code == 0) {
token = msg.data;
} console.log("token="+token);
}
}); });
</script>
<body>
<button id="getData">获取数据</button>
</body>
</html>

可以看到操作成功!


通过以上就可以把session存在我自己的容器里面,但是其实还是比较耗内存,因为这样需要把session在内存中存两份,服务器内置容器中一份,我自己的容器中一份。这个问题留着后面解决。

MZY项目笔记:session歧路的更多相关文章

  1. Django商城项目笔记No.2项目准备工作

    Django商城项目笔记No.2项目准备工作 接着上篇开始,创建好工程之后,随之而来的是怎么配置工程,这篇文章记录如何进行相关的配置 1.pycharm打开工程,进行相关的配置 通过pycharm打开 ...

  2. Django项目笔记:sessions处理以及复杂对象序列化

    前言:一点题外话 我发现,不更新博客的时候,不是非常忙,就是效率非常低.最近没怎么更新博客,原因是第二种= =.惭愧惭愧. 今天效率出奇的高,一天时间把PassNote后端的接口全部写完了,Djang ...

  3. 《BI项目笔记》——微软BI项目笔记连载

    本系列文章主要是结合实际项目,加上自己的总结,整理出来的一系列项目笔记,涉及微软SQL Server2008中商务智能开发中的SSAS.SSIS模块:  准备工作: <BI项目笔记>基于雪 ...

  4. 项目笔记---CSharp图片处理

    原文:项目笔记---CSharp图片处理 项目笔记---CSharp图片处理 最近由于项目上需要对图片进行二值化处理,就学习了相关的图片处理上的知识,从开始的二值化的意义到动态阀值检测二值化等等,并用 ...

  5. 同一个tomcat多个项目共享session,一个tomcat两个项目共享sessionId

    同一个tomcat多个项目共享session,一个tomcat两个项目共享sessionId >>>>>>>>>>>>>& ...

  6. laravel 多个项目共享SESSION

    只讨论一个域下的项目. eg: a.xxx.com 和 b.xxx.com 来共享session 如果多个laravel项目共享SESSION要满足以下条件: SESSION可以存放在一个地方,eg: ...

  7. Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid

    Django商城项目笔记No.12用户部分-QQ登录2获取QQ用户openid 上一步获取QQ登录网址之后,测试登录之后本该跳转到这个界面 但是报错了: 新建oauth_callback.html & ...

  8. Django商城项目笔记No.11用户部分-QQ登录1获取QQ登录网址

    Django商城项目笔记No.11用户部分-QQ登录 QQ登录,亦即我们所说的第三方登录,是指用户可以不在本项目中输入密码,而直接通过第三方的验证,成功登录本项目. 若想实现QQ登录,需要成为QQ互联 ...

  9. Django商城项目笔记No.10用户部分-登录接口

    Django商城项目笔记No.10用户部分-登录接口 添加url路由 接下来第二步,增加返回内容: 增加结果如下: 配置:上边的方法定义了返回的内容都有哪些,那这个方法jwt还不知道,需要配置: 修改 ...

随机推荐

  1. Leetcode4. 寻找两个正序数组的中位数

    > 简洁易懂讲清原理,讲不清你来打我~ 输入两个递增数组,输出中位数![在这里插入图片描述](https://img-blog.csdnimg.cn/25550994642144228e9862 ...

  2. 基于小熊派Hi3861鸿蒙开发的IoT物联网学习【二】

    HarmonyOS内核开发-信号量开发案例学习记录   一.LiteOS里面的任务管理介绍: 任务状态通常分为以下四种: 就绪(Ready):该任务在就绪列表中,只等待CPU. 运行(Running) ...

  3. 迈达斯midas Gen 2019 2.1 中文汉化安装教程

    midas Gen 2019 v2.1 for win是一款关于结构设计有限元分享的工具,分为建筑领域.桥梁领域.岩土领域.仿真领域四个大类.具有人性化的操作界面,且采用了优秀的的计算机显示技术,是建 ...

  4. spring 读取account-service中的值

    account-service //main--resources--account-service.properties 文件位置 email.protocol=smtps email.host=s ...

  5. post传参params与body的区别(@RequestParam和@RequestBody的区别)

    1.axios post请求  Content-Type默认为 application/x-www-form-urlencoded,我们传递参数的时,params里面的参数(简单的对象,通过 &quo ...

  6. wireshark常见分析

    转载于https://www.cnblogs.com/sn1per/p/12553064.html https://www.cnblogs.com/csnd/p/12332421.html 直接看上面 ...

  7. leetcode 有效三角形的个数

    题目描述: 平明伞兵解法: 既然要求满足三角形要求的三边,简单来说,就是最短两边之和大于第三边,所以,第一步Arrays.sort().先排序,然后直接伞兵暴力法,三重循环.当然最后肯定是能跑出来的, ...

  8. 浅谈Java类中的变量初始化顺序

    一.变量与构造器的初始化顺序 我们知道一个类中具有类变量.类方法和构造器(方法中的局部变量不讨论,他们是在方法调用时才被初始化),当我们初始化创建一个类对象时,其初始化的顺序为:先初始化类变量,再执行 ...

  9. .NET5控制台程序使用EF连接MYSQL

    .NET5控制台程序使用EF连接MYSQL 1.使用nuget下载: Microsoft.Extensions.Configuration.Json Pomelo.EntityFrameworkCor ...

  10. 解决:无法从 Windows 应用商店下载。请检查网络连接

    今天在安装wsl的时候,装了几次一直中断,一直提示正在从Windows 应用商店下载,网络无法连接... 每次都是加载到2%就断了.网上搜了一圈,找到以下2种解决办法: 修改DNS把DNS修改为微软的 ...