一:重复登录问题

随着互联网公司的项目在微服务和分布式的环境下进行的搭建,
导致一个项目可能分别部署在几个甚至很多的服务器集群下,此时就会出现一个问题
当用户进行一个session会话的时候,比如一个用户去登录项目,
一般的大公司的项目都是有Nginx进行反向代理的,
但是这里简单列举一下Nginx常用的几种反向代理策略:1.轮询策略,2. 权重比例策略,3. ip_hash策略,
4. 还可以自定义的策略,在Nginx的反向代理下,
一般会把用户的请求分发到不同的服务器上,
但是如果用户请求的请求是存放在该请求的服务器A上,
那么该用户的sessionID就存储在该服务器上JVM的一个ConcurrentHashmap中,以sessionID为key。
但是如果此时用户请求的一个服务模块可能需要调用到服务器B,
当用户发起请求的时候,此时的服务器B上并没有存储该用户的sessionID,
所以就会再次让用户进行一个登陆操作。还有可能会导致用户本来就想完成一个下单操作,
但是却还登陆了好几次的情况。
所以session共享方案在分布式环境和微服务系统下,显得尤其重要。

方案一:基于Nginx(或其他负载的软件或硬件)的ip_hash 负载均衡

其实就是对请求过来的ip地址对你的多少台可用的服务器进行取模,然后就会把你的请求通过Nginx的反向代理给分发到对应的服务器上。(这里会把可用的服务器放到一个数组中,如果取模得到的结果是几,就把请求分到服务器数组中的下标为几 的服务器上)

需要你在Nginx.conf文件中进行对应的修改,根据自己的可用服务器
upstream backend{ip_hash;server 192.168.128.1:8080 ;server 192.168.128.2:8080 ;server 192.168.128.3:8080 down;server 192.168.128.4:8080 down;}
server {listen 8081;server_name test.csdn.net;root /home/system/test.csdn.net/test;location ^~ /Upload/upload {proxy_pass http://backend;}


方案二:基于Tomcat的session复制
这个解决方案其实就是当用户请求的时候,把产生的sessionID给复制到系统所有的服务器中,这样就能保证当用户请求的时候从服务器A可能调用到服务器B上的模块的时候,也能保证服务B也有该用户的sessionID,这样就不会再次让用户进行再次登录操作了。也就解决问题了。

1、tomcat与redis集成实现session共享:
环境为tomcat7 + jdk1.7或1.8的话:
在所有需要共享session的服务器的tomcat中目录下:
lib目录中添加以下三个jar包,测试通过:

conf目录中content.xml中加入:配置redis服务

2、如jkd1.8+tomcat7,在137和139两台tomcat中加入jar包且进行如上配置:
在这里插入图片描述

在这里插入图片描述

添加两个注意点
1、按照如上配置,使用redis数据库,放入session中的对象必须要实现java.io.Serializable接口,使用memcache的可以不用实现Serializable接口
原因是:因为tomcat里使用的将session放置redis使用的工具类,是使用的jdk序列化模式存储的,这一点也是很容易理解的,session.setAttribute(String key, Object value),存储Object类型
object放入redis中又要能取出来,只能是序列化进行存储了,然后取出的时候进行反序列化。
所以我们在session中存储的任何对象,都必须实现序列化接口。
2、按照如上配置,使用redis做session存储空间时,web应用的session-time的时间单位会变成[秒],而不是原本的[分]
原因是:因为tomcat里使用的将session放置redis使用的工具类,在存储时为对tomcat容器时间做转换
在redis中设置过期时间是使用秒作为单位的,有个命令叫expire可以设置redis键值过期时间,所以在context.xml配置文件中我们需要制定session过期时间(默认是60秒,配成1800即30分钟),这一点很重要。
请注意!!!!
context.xml配置说明:

方案三:使用Redis做缓存session的统一缓存
每次用户的请求的时候生成的sessionID给放到Redis的服务器上。然后在基于Redis的特性进行设置一个失效时间的机制,这样就能保证用户在我们设置的Redis中的session失效时间内,都不需要进行再次登录。
一:
1、引入相关jar包:
这里需要引入Spring Session和Spring Data Redis相关的依赖jar包。可以自行从maven仓库下载,也可以参考使用的jar包:down.51cto.com/data/228183…
2、 修改spring-data-redis相关配置:
在项目的spring-data-redis相关配置中添加相关配置
3、修改web.xml:
在web.xml中添加以下filter:springSessionRepositoryFilter
org.springframework.web.filter.DelegatingFilterProxy
4、这个filter放在第一位,其他的如编码、shiro等filter需要放在这之后
到此,Spring Session和Spring Data Redis就整合到项目中了
二: Spring Session 集群解决方案
· HttpSession - 允许以应用程序容器(即 Tomcat)中性的方式替换 HttpSession。
· 将 session 所保存的状态卸载到特定的外部 session 存储中,如 Redis 或 Apache Geode
中,它们能够以独立于应用服务器的方式提供高质量的集群。
· 支持每个浏览器上使用多个 session,从而能够很容易地构建更加丰富的终端用户体验。
· 控制 session id 如何在客户端和服务器之间进行交换,这样的话就能很容易地编写 Restful API,因为它 · 可以从 HTTP头信息中获取 session id,而不必再依赖于 cookie。
· 当用户使用 WebSocket 发送请求的时候,能够保持 HttpSession 处于活跃状态。
用:spring-session-data-redis
1、引入包

<dependency><groupId>org.springframework.session</groupId><artifactId>spring-session-data-redis</artifactId>
</dependency>

2、Session 配置

@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 86400*30)
public class SessionConfig {
}
maxInactiveIntervalInSeconds: 设置 Session 失效时间,使用 Redis Session 之后,
原 Boot 的 server.session.timeout 属性不再生效。

3、实现模拟登陆
添加登陆方法和注册方法:
添加登录方法,登录成功后将用户信息存放到 Session 中。

@RequestMapping(value = "/login")
public String login (HttpServletRequest request,String userName,String password){String msg="登陆失败!";User user= userRepository.findByUserName(userName);if (user!=null && user.getPassword().equals(password)){request.getSession().setAttribute("user",user);msg="登陆成功!";}return msg;
}

定义 index 方法,只有用户登录之后才会看到:index content 这条信息否则提示请先登录。

@RequestMapping(value = "/index")
public String index (HttpServletRequest request){String msg="首页内容";Object user= request.getSession().getAttribute("user");if (user==null){msg="请先登录!";}return msg;
}

测试流程:
访问:http://localhost:8800/index和http://localhost:8899/index都会提示先登录。
用8800窗口登陆:localhost:8800/login?userName=xiaoli&password=123456。
登陆成功后访问首页:显示首页内容,8899端口直接访问首页,我们发现显示首页内容,则实现了session共享。

@RequestMapping(value = "/logout")public String logout (HttpServletRequest request){HttpSession session=request.getSession();session.removeAttribute("user");return "";}

方案四: 把session放到cookie中
每次用户请求的时候,都会把自己的cookie放到请求中,所以这样就能保证每次用户请求的时候都能保证用户在分布式环境下,也不会在进行二次登陆。

关于单点登录和SSO的思考

1、单点登录和传统的区别,单点登录和免登陆的区别,单点登录和内嵌方式,及iframe等方式的使用区别,

2、sso登录以后,可以将Cookie的域设置为顶域,即.a.com,这样所有子域的系统都可以访问到顶域的Cookie。我们在设置Cookie时,只能设置顶域和自己的域,不能设置其他的域。比如:我们不能在自己的系统中给baidu.com的域设置Cookie。
----如果不在一个顶级域中???跨域还跨区,Nginx可以帮助拿到cookie中的信息,就是在A系统转发中把信息写到(B服务器端)的Nginx中,然后B服务从Nginx中获取cookie的信息做验证。

重复登录问题解决的方案汇总相关推荐

  1. 浅谈单点登录SSO实现方案 | StartDT Tech Lab 06

    写在前面 这是奇点云全新技术专栏「StartDT Tech Lab」的第6期. 在这里,我们聚焦数据技术,分享方法论与实战.一线的项目经历,丰富的实践经验,真实的总结体会-滑到文末,可以看到我们的往期 ...

  2. 防止用户重复登录解决方案

    前一段时间碰到一个需求:一个账号只能登录一次,不能重复登录问题. 在网上找了下,大概有两种解决方案: 1.通过数据库状态位判断该用户是否已经登录. 2.利用session监听器监听每一个登录用户的登录 ...

  3. 群星怎么让服务器稳定,DL服务器主机环境配置(ubuntu14.04+GTX1080+cuda8.0)解决桌面重复登录...

    前面部分是自己的记录,后面方案部分是成功安装驱动+桌面的正解 问题的开始在于:登录不了桌面,停留在重复输入密码界面 博文中分析的结论: 虚拟机中不能直接调用物理显卡进行 CUDA 编程:虚拟机中运行 ...

  4. 总奖金200万的算法赛方案汇总!

    2021DIGIX全球校园AI算法赛方案汇总 关于赛事信息(比赛8月底截止,点击下方可跳转) 地址:https://gitee.com/coggle/competition-baseline/tree ...

  5. Android适应方案汇总(三)

    在Android适应方案汇总(一个).(两)在.我们理解一些基本概念. 那么详细的开发,我们应该重视起来. 首先,我们需要知道.关键的事实是,这两个适配器: (1).这点在单位的使用上用dp.sp以及 ...

  6. 防止论坛用户重复登录的方法 .

    本例完成的功能就是防止用户重复登录!若用户已经登录,则当其再次登录时,弹出提示框后返回! 实现思路:用户登录成功后,将用户登录信息存放到Hashtable类型的Application["On ...

  7. 怎么样设置关闭网页再次登录网页是正常登录状态_学籍系统出现“该账号已登录,不能重复登录”怎么办?...

    学籍系统因保密需要,限定一台电脑只能同时登录一个账号,所以大家在退出学籍系统时,不要直接关闭网页窗口退出系统,这样学籍系统实际仍然在登录状态,当我们重新登录系统时,就会出现提示"该账号已登录 ...

  8. 使用session监听+spring MVC拦截器禁止用户重复登录

    在许多web项目中,需要禁止用户重复登录.一般来说有两种做法: 一是在用户表中维护一个字段isOnLine(是否在线),用户登录时,设定值为true,用户退出时设定为false,在重复登录时,检索到该 ...

  9. 我是SQL小菜鸟---SQL全局临时表防止用户重复登录

    先介绍一下什么是sql临时表及使用方法 临时表  SQL Server 支持临时表.临时表就是那些名称以井号 (#) 开头的表.如果当用户断开连接时没有除去临时表,SQL Server 将自动除去临时 ...

最新文章

  1. 简单了解request与response
  2. 中国联想和浪潮最能算,雄霸全球超算TOP 500数量榜单
  3. python3报错:importError: dynamic module does not define module export function (PyInit_cv_bridge_boost
  4. 跟我一起学docker(四)--容器的基本操作
  5. 多线程并发下的单例模式
  6. swift5以上版本的代理的实现,详细教你书写代理
  7. oracle varchar2改成大字段类型clob,读取大字段内容
  8. Android 5.0有哪些变化
  9. django学习笔记03
  10. 【语音处理】音频信号分析仪Matlab系统
  11. 电商项目——初识电商——第一章——上篇
  12. Windows系统邮件中如何绑定QQ邮箱
  13. APP设计:(一)app界面常用设计规范
  14. sap税码配置_SAP税务管辖码Tax Jurisditcion code功能(1)
  15. 《人月神话》-人月神话
  16. Java实现 蓝桥杯VIP 算法提高 促销购物
  17. 横版格斗——技能动作概念
  18. 13、恩智浦-S32K11X:ADC实验
  19. Python简介以及在网站中运行Python
  20. servers split sql_SQL中实现SPLIT函数几种方法总结(必看篇)

热门文章

  1. 烽火AN5516 OLT通过OMCI下发 PPPoE WAN连接问题分析-----OLT存在私有Me协议
  2. 检查DNT.config中Dbtype节点数据库类型是否正确,例如:SqlServer、Access、MySql
  3. 大型网站存储瓶颈(广义水平拆分)
  4. 30个HTML+CSS前端开发案例(五)
  5. 09盘点:梦幻诛仙蜀门剑网三的营销启示
  6. 《从菜鸟到大师-杨老师课程笔记》Python工程师之 01
  7. 百度人脸识别的两个方式的使用
  8. MongoDB安装过程中出现service MongoDB failed to start,verify that you have sufficient privileges to start...
  9. 写给大忙人看的_软件测试简历范文
  10. 【IT软件专利】---专利编写步骤