JAVA SSM框架+Redis 实现单点登录

1:什么是单点登录?

答:单点登录的英文名叫做:Single Sign On(简称SSO

一般我们的模块都是在同一个系统下,同一个tomcat(如图,以商城为例)
img

后来为了维护和资源我们把一个系统拆成多个子系统。

img

而单点登录就是其中的一部分。

我们有多个系统,每个系统都要输入一次账号和密码的话就会变得很麻烦,这时候就需要单点登录,只要其中一个子系统登录的话,其他系统都能自动登录。最为熟悉的例子就是淘宝和天猫,如果你淘宝登录后,打开天猫就能自动登录无需再输入账号和密码。

2:实现单点登录的思路(整个页面的流程)

img

假设两个页面

用户A系统没登陆,B系统没登陆

这时用户在A登陆,A生成token令牌存入cookie,redis存入已经登录参数

然后用户打开B系统登录页面,B系统登录页面发送请求,后端通过cookie获取到用户在A系统登录的信息

判断获取到的信息没有错误进行自动登陆

3:Demo代码(两个页面的代码是一样的,路径什么的改改就行了)

简单的登陆jq,ajax请求

前端

<body background="jquery/loginbg.jpg">
<div>
<form  style="margin: auto; width:230px" class="form-signin"  >
<h2 class="form-signin-heading"><font color="white">SSO1用户登录</font></h2>
<!-- <label>账号:</label> -->
<input type="text" id="txtUsername" class="form-control" name="username" placeholder="请输入账号" /><br/>
<!-- <label>密码:</label> -->
<input type="password" id="txtPassword" class="form-control" name="password" placeholder="请输入密码" /><br/>
<!-- <input type="submit" value="提交" /> --><a class="btn btn-primary btn-block" id="tijiao">提交</a><br>
<!-- <button class="btn btn-primary btn-block"  id="tijiao">提交</button><br> --><button class="btn btn-primary btn-block"  >重置</button><br>
<!-- <input type="reset" value="重置" /> -->
<input type="button" class="btn btn-primary btn-block" value="注册" onclick="window.location.href='add.jsp';"/>
</div>
<div id="chartmain" style="width:600px; height: 400px;  margin: auto; " class="form-signin"></div></body>
<script type="text/javascript">$("#tijiao").click(function(){var paramMap = {};paramMap.username = $("#txtUsername").val();paramMap.userpasswd = $("#txtPassword").val();$.ajax({type:'POST',data:JSON.stringify(paramMap),dataType:'JSON',url:"user/slogin",contentType :"application/json;charset=UTF-8",async: true,error:function(jqXHR){alert("发生错误:"+ jqXHR.status); },success:function(data){if(data){if(data.state == "success"){window.location.href ='index.jsp';}else if(data.state == "fault"){window.location.href ='login.jsp';} }}});})window.onload = function(){var paramMap = {};var i = 0;paramMap.username = $("#txtUsername").val();paramMap.userpasswd = $("#txtPassword").val();$.ajax({type:'POST',data:JSON.stringify(paramMap),dataType:'JSON',url:"user/slogin",
// 			xhrFields: {
// 		        withCredentials: true // 携带跨域cookie
// 		    },contentType :"application/json;charset=UTF-8",async: true,error:function(jqXHR){alert("发生错误:"+ jqXHR.status); },success:function(data){if(data){if(data.state == "success"){window.location.href ='index.jsp';}else if(data.state == "fault"){debugger;var str=location.href; //取得整个地址栏var num=str.indexOf("=") str=str.substr(num+1);if(str!="1"||str==null){window.location.href ='login.jsp?state=1';}} }}});
}
</script>

后端

	/*** 登陆* @param <Account>* @param model* @param session* @return* @throws Exception */@ResponseBody@RequestMapping(value = "/slogin", method = RequestMethod.POST)public ResultInfo slogin(@RequestBody Map<String, String> param,HttpSession session, HttpServletRequest request,ServletResponse response, HttpServletResponse responses)throws Exception {ResultInfo resultinfo = new ResultInfo();/*** 判断redis是否连接成功*///连接本地的 Redis 服务@SuppressWarnings("resource")Jedis jedis = new Jedis("localhost");System.out.println("连接成功");//用户验证String username = param.get("username");String passwd = param.get("userpasswd");if(jedis.exists("islogin")){//判断是否已经登录if(!jedis.get("islogin").equals("1")){// TODO: handle exceptionresultinfo.setState(StateType.fault);jedis.set("islogin", "0");}}else if(!jedis.exists("islogin") && username.length()==0 && passwd.length()==0){resultinfo.setState(StateType.fault);return resultinfo;}/*** 从cookie中获取数据*/Cookie[] cookies = request.getCookies();System.out.println(cookies);String cookievalue = null;for(Cookie cookiexs : cookies){if(cookiexs.getName().equals("token")){cookievalue = cookiexs.getValue();break;}}if(cookievalue!=null){//base64解密String decusername = null;String decpasswd = null;int a = 1;byte[] decoded = Base64Utils.decode(cookievalue.getBytes());String decodeStr = new String(decoded,"UTF-8");System.out.println("Base 64 解密后:" + decodeStr);//获取用户名和密码for(int i=-1; i<=decodeStr.lastIndexOf("=");++i){i=decodeStr.indexOf("=",i);System.out.print(i+"\t");if(a==1){decusername = decodeStr.substring(i, i);a++;}else if(a>1){decusername = decodeStr.substring(5,i-6);decpasswd = decodeStr.substring(i+1, decodeStr.length()-6);a=1;}System.out.println("账号为:"+decusername+"\t"+"密码为:"+decpasswd);}username = decusername;passwd = decpasswd;}try {if(username  != "" && passwd !=""){User user = userService.loginUsername(username);if(user ==null){resultinfo.setState(StateType.fault);jedis.set("islogin", "0");return resultinfo;}else if(!user.getPassword().equals(passwd)){resultinfo.setState(StateType.fault);jedis.set("islogin", "0");return resultinfo;}//设置tokenString token = tokenset(user);//将数据保存到cookie中Cookie cookie = new Cookie("token", token);//cookie.setMaxAge(600);responses.addCookie(cookie);//将token发送给客户端,附带本次全局会话的sessionId//String allSessionId=request.getSession().getId();//获取sessionidString sessionid = session.getId();//设置状态(通过session判断该浏览器与认证中心的全局会话是否已经建立),生成令牌//判断用户是否登录request.getSession().setAttribute("isLogin", username);Map<String, String> tosession = new HashMap<String, String>();tosession.put("sessionid", sessionid);jedis.set("islogin", "1");jedis.set(token,username+passwd);jedis.expire("islogin", 120);
//				jedis.expire("token", 600);resultinfo.setData(token);resultinfo.setState(StateType.success);}if(jedis.get("islogin").equals("1")){resultinfo.setState(StateType.success);}else{resultinfo.setState(StateType.fault);}} catch (Exception e) {// TODO: handle exceptionresultinfo.setState(StateType.fault);resultinfo.setData(e.toString());}return resultinfo;}
     /*** 设置token*/private String tokenset(User user) {// TODO Auto-generated method stubString token = null;String sign = "hitomi";String param = "name="+user.getUsername()+"passwd="+user.getPassword()+sign;token = Base64Utils.encodeToString(param.getBytes());return token;}

此代码只是简单的实现单点登录的思路和功能,仅供参考

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556972.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2017云栖大会门票转让_「揭秘GP」云栖大会 | Greenplum 6.0 内核优化解读和7.0展望...

9月25日&#xff0c;云栖大会在杭州阿里巴巴云栖小镇正式拉开序幕&#xff0c;三天会议期间&#xff0c;共吸引了200多位世界级科学家、400多家科技合作伙伴参与&#xff0c;科技展区面积超过3万平方米&#xff0c;共发布了1000多项顶尖技术。云栖大会现场在此次云栖大会上&…

从mysql到大数据(一)--开宗明义

一、大数据长什么样 长像很普通&#xff0c;至少看两眼后就觉得很平常。 举个栗子&#xff1a; 一个表格&#xff0c;学生信息表&#xff0c;里面有学号、姓名、性别、年龄、学校、学院、专业、年级、宿舍号等信息如下&#xff0c; 但是表在库里&#xff0c;我们想看&#xf…

SSO单点登录方案大全

分布式微服务系统主流常用的登录方案 前言: 单点登录其实是一个概念,主要是为了解决一次登录,多系统(本系统或外部系统)之间不需要重复登录的问题,就目前来说,主流的解决方案针对业务场景分为3个方向: 1: 同一公司,同父域下的单点登录解决方案. 如[http://map.baidu.com][[h…

em算法怎么对应原有分类_机器学习基础-EM算法

EM算法也称期望最大化(Expectation-Maximum,简称EM)算法&#xff0c;它是一个基础算法&#xff0c;是很多机器学习领域算法的基础&#xff0c;比如隐式马尔科夫算法(HMM)&#xff0c; LDA主题模型的变分推断等等。本文就对EM算法的原理做一个总结。EM算法要解决的问题我们经常会…

postman插件下载、安装教程

这里只讲如何在Chrome 中安装postman插件 下载链接&#xff1a;https://pan.baidu.com/s/1vampHeD0UiDNbrB3G8j_hA 提取码&#xff1a;wqdl 方法/步骤 1.在Chrome输入地址&#xff1a;[chrome://extensions/] 2.将压缩包直接拖拽至Chrome中 3.运行在Chrome输入地址&#xff…

得力条码扫描器怎么用_广东智能物流控制系统怎么选

广东智能物流控制系统怎么选&#xff0c;东莞智库&#xff0c;东莞智库(SmartWarehouse)&#xff0c;专注电子制造SMT智能仓库&#xff0c;致力于帮助电子制造企业提高物流仓储效率和效能。广东智能物流控制系统怎么选&#xff0c; 旭日东自动分拣系统是个集机械、电气、计算机…

从mysql到大数据(三)--mysql数据库建模一常用数据类型及引擎

数据库的安装请自行百度。如果你想直捣黄龙练查询&#xff0c;没有表没有数据是不能实现的。我们从建表开始学习。但要知道&#xff0c;我们所有东西都是了解&#xff0c;学习不要有压力&#xff0c;不要必须要求记什么&#xff0c;当然&#xff0c;如果你不累可以记&#xff0…

Postman用法简介-Http请求模拟工具

Postman用法简介-Http请求模拟工具 在我们平时开发中&#xff0c;特别是需要与接口打交道时&#xff0c;无论是写接口还是用接口&#xff0c;拿到接口后肯定都得提前测试一下&#xff0c;这样的话就非常需要有一个比较给力的Http请求模拟工具&#xff0c;现在流行的这种工具也…

matlab多元函数_函数的计算机处理8(1)_1MATLAB

计算机语言运用--数值计算8-函数的计算机处理8(1)_1MATLAB计算机&#xff1a;电子线路组成的计算机器。人与计算机则是通过计算机语言-符号系统说给计算机听而交流。计算机语言有低级语言-机器语言、汇编、高级语言-C/C/C#/VB/PASCAL/LISP/JAVA/PYTHON/……成百上千种之多。 作…

java 怎么通过url获取远程服务器上某个文件夹下的所有文件_JMX远程代码漏洞研究...

前言&#xff1a;前一段时间apace solr JMX因为配置不当出现远程代码执行漏洞&#xff0c;最近自己在看一套java系统时&#xff0c;发现该系统也存在JMX远程代码漏洞&#xff0c;于是乎就想研究下JMX这种通用型漏洞&#xff0c;下面我就从原理到利用对该漏洞做一个简单的梳理。…

app每秒并发数_性能测试连载 (38) jmeter 线程数与性能测试的负载模式

点击跳转>>jmeter--由浅入深学性能系列需求下面有3个场景&#xff0c;思考一下在jmeter里面如何设计场景1&#xff1a;有一个项目&#xff0c;500用户同时登录&#xff0c;响应时间能达到多少场景2&#xff1a;考勤打卡&#xff0c;最大吞吐量能达到多少(每秒最大能完成多…

用自定义注解做点什么——自定义注解有什么用

用自定义注解做点什么 前言 你不一定听过注解&#xff0c;但你一定对Override不陌生。 当我们重写父类方法的时候我们就看到了Override。我们知道它表示父类方法被子类重写了。 现在告诉你&#xff0c;Override就是一个注解。 也许你会疑惑注解是什么&#xff1f; 注解&…

c++ 查找文件夹下最新创建的文件_云计算开发总结:搜索Linux文件和文件夹的方法...

当下&#xff0c;随着Linux在物联网、云技术、超级计算和人工智能等领域扮演关键角色&#xff0c;各种会议和新版本的发布令人应接不暇&#xff0c;Linux将迎来一个激动人心的“云时代”。如果你想把握这个风口&#xff0c;现在是学习Linux技术的最佳时期。今天千锋广州云计算培…

RSA 非对称加密原理

RSA 加密原理 步骤说明描述备注1找出质数P 、Q-2计算公共模数N P * Q-3欧拉函数φ(N) (P-1)(Q-1)-4计算公钥E1 < E < φ(N)E的取值必须是整数 E 和 φ(N) 必须是互质数5计算私钥DE * D % φ(N) 1-6加密C &#xff1d; M E mod NC&#xff1a;密文 M&#xff1a;明文7…

浅谈对称加密与非对称加密

在数字加密算法中&#xff0c;通过可划分为对称加密和非对称加密。 一&#xff1a;什么是对称加密&#xff1f; 在对称加密算法中&#xff0c;加密和解密使用的是同一把钥匙&#xff0c;即&#xff1a;使用相同的密匙对同一密码进行加密和解密&#xff1b; 加密过程如下&…

ios跨线程通知_一种基于Metal、Vulkan多线程渲染能力的渲染架构

快手Y-tech 原创最新技术干货分享随着3D渲染场景规模越来越复杂&#xff0c;单线程渲染架构在满足业务性能要求时已经捉襟见肘&#xff0c;因此&#xff0c;多线程渲染显得愈发重要。本文首先介绍了新一代图形渲染接口Metal、Vulkan&#xff0c;以及它们的多线程渲染特性&…

58同城面试盘点

58同城面试盘点 1.一张订单表&#xff0c;有user_name,order_id,order_time,order_amount 四个字段&#xff0c;怎么取出每个用户2021年10月以来第一个订单的金额&#xff08;下单时间格式为’yyyy-MM-dd HH:mm:ss’&#xff09;&#xff1f; select user_name,order_id,orde…

stringbuffer判断是否为空

StringBuffer sbnew StringBuffer();if(sb!null && sb.length()>0){System.out.println("证明sb不为空!"); }

virtualbox: win11主机安装deepin双向复制问题

virtualbox: win11主机安装deepin双向复制问题1.安装virtualbox增强组件(确保光驱可用)2.终端挂载3. 运行BoxLinuxAdditions4. 重启虚拟机&#xff0c;验证OK&#xff01;使用virtualbox安装深度系统deepin虚拟&#xff0c;发现虚拟机和宿主机之间不能双向复制&#xff0c;已经…

基坑监测日报模板_刚刚!温州瓯海突发塌陷,初步判断为临近地块地下室基坑支护桩移位...

资料来源&#xff1a;瓯海新闻网 | 温州百事通 | 土木吧 | 岩土新鲜事 等版权归原作者所有如有侵权请联系删除9月10日中午11点左右&#xff0c;温州市瓯海区娄桥街道商汇路道路塌陷。塌陷路面位于商汇路的公交车站旁&#xff0c;几十米长的路面已经开裂&#xff0c;公交站台发生…