JAVA SSM框架+Redis 实现单点登录
1:什么是單點(diǎn)登錄?
答:單點(diǎn)登錄的英文名叫做:Single Sign On(簡稱SSO)
一般我們的模塊都是在同一個(gè)系統(tǒng)下,同一個(gè)tomcat(如圖,以商城為例)
后來為了維護(hù)和資源我們把一個(gè)系統(tǒng)拆成多個(gè)子系統(tǒng)。
而單點(diǎn)登錄就是其中的一部分。
我們有多個(gè)系統(tǒng),每個(gè)系統(tǒng)都要輸入一次賬號(hào)和密碼的話就會(huì)變得很麻煩,這時(shí)候就需要單點(diǎn)登錄,只要其中一個(gè)子系統(tǒng)登錄的話,其他系統(tǒng)都能自動(dòng)登錄。最為熟悉的例子就是淘寶和天貓,如果你淘寶登錄后,打開天貓就能自動(dòng)登錄無需再輸入賬號(hào)和密碼。
2:實(shí)現(xiàn)單點(diǎn)登錄的思路(整個(gè)頁面的流程)
假設(shè)兩個(gè)頁面
用戶A系統(tǒng)沒登陸,B系統(tǒng)沒登陸
這時(shí)用戶在A登陸,A生成token令牌存入cookie,redis存入已經(jīng)登錄參數(shù)
然后用戶打開B系統(tǒng)登錄頁面,B系統(tǒng)登錄頁面發(fā)送請求,后端通過cookie獲取到用戶在A系統(tǒng)登錄的信息
判斷獲取到的信息沒有錯(cuò)誤進(jìn)行自動(dòng)登陸
3:Demo代碼(兩個(gè)頁面的代碼是一樣的,路徑什么的改改就行了)
簡單的登陸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>賬號(hào):</label> --> <input type="text" id="txtUsername" class="form-control" name="username" placeholder="請輸入賬號(hào)" /><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("發(fā)生錯(cuò)誤:"+ 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("發(fā)生錯(cuò)誤:"+ 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; //取得整個(gè)地址欄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 服務(wù)@SuppressWarnings("resource")Jedis jedis = new Jedis("localhost");System.out.println("連接成功");//用戶驗(yàn)證String username = param.get("username");String passwd = param.get("userpasswd");if(jedis.exists("islogin")){//判斷是否已經(jīng)登錄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中獲取數(shù)據(jù)*/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("賬號(hào)為:"+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;}//設(shè)置tokenString token = tokenset(user);//將數(shù)據(jù)保存到cookie中Cookie cookie = new Cookie("token", token);//cookie.setMaxAge(600);responses.addCookie(cookie);//將token發(fā)送給客戶端,附帶本次全局會(huì)話的sessionId//String allSessionId=request.getSession().getId();//獲取sessionidString sessionid = session.getId();//設(shè)置狀態(tài)(通過session判斷該瀏覽器與認(rèn)證中心的全局會(huì)話是否已經(jīng)建立),生成令牌//判斷用戶是否登錄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;} /*** 設(shè)置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;}此代碼只是簡單的實(shí)現(xiàn)單點(diǎn)登錄的思路和功能,僅供參考
總結(jié)
以上是生活随笔為你收集整理的JAVA SSM框架+Redis 实现单点登录的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工业用微型计算机(20)-指令系统(15
- 下一篇: linux cmake编译源码,linu