JAVA SSM框架+Redis 实现单点登录
生活随笔
收集整理的這篇文章主要介紹了
JAVA SSM框架+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 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;}此代碼只是簡單的實現單點登錄的思路和功能,僅供參考
總結
以上是生活随笔為你收集整理的JAVA SSM框架+Redis 实现单点登录的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 工业用微型计算机(20)-指令系统(15
- 下一篇: 嵌入式笔录(7)