JAVA SSM框架下+Redis 实现单点登录(手把手教,一步步都很详细)

Redis的安装和引用参考上一篇:Redis的安装(java引用Redis)

1:什么是单点登录?

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

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

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

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

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

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

假设两个页面

用户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 exception
				resultinfo.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;
				}
				//设置token
				String token = tokenset(user);
				
				//将数据保存到cookie中
				Cookie cookie = new Cookie("token", token);
				//cookie.setMaxAge(600);
				responses.addCookie(cookie);
				
				//将token发送给客户端,附带本次全局会话的sessionId
				//String allSessionId=request.getSession().getId();
				
				//获取sessionid
				String 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 exception
			resultinfo.setState(StateType.fault);
			resultinfo.setData(e.toString());
		}
		return resultinfo;
			
		
		
	}

 

/**
	 * 设置token
	 */
	private String tokenset(User user) {
		// TODO Auto-generated method stub
		String token = null;
		String sign = "hitomi";
		String param = "name="+user.getUsername()+"passwd="+user.getPassword()+sign;
		token = Base64Utils.encodeToString(param.getBytes());
		return token;
		
	}

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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
随着互联网应用的快速发展,Java EE成为当下互联网开发中最为流行的开发语言之一。而在Java EE开发中,轻量级框架的整合是必不可少的一部分。其中SSM框架是最先被广泛应用的一种框架,它是由Spring、SpringMVC和MyBatis三个框架整合而成。此外,Spring框架也是Java EE开发中非常重要的一部分,它主要提供了全部企业级应用的核心技术和API,包括依赖注入、控制反转等。 对于如何提高web应用的性能,Redis是一个非常强大的缓存解决方案。它是一种内存数据存储系统,能提供快速读取数据、支持分布式和高可用性等特性。当然,Redis的应用需要和Java EE整合,才能更好地发挥其功能。 最近几年,微服务架构也成为Java EE中非常关注的技术趋势。微服务架构是一种面向服务的架构,它将一个应用程序拆分成若干个服务,这些服务之间通过API方式进行互相通信。微服务架构可以执行部署,提高应用可扩展性,从而更好地满足应用程序的要求和需求。 最后,在Java EE开发中,PDF文档的生成和处理也是一个非常重要的任务。开发人员可以使用PDF框架来生成各种类型的PDF文档,满足企业应用的需求和要求。 总的来说,以上几种Java EE互联网轻量级框架整合开发技术都非常重要,可以提高应用程序的开发效率和可用性,同时也能提高web应用程序在互联网中的性能和可扩展性,提供更好的用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值