单点登录是什么呢,简单的来说吧,你去旅游景点参观,里面有一种票叫做全票(也不知道是不是这个,反正就是有这个票里面所有的景区你都可以去参观),还有一种票就是单个景区的票,这个票只是这个景区可以用,到了其它的景点就要再买票了。单点登录就类似于全票,只要和这个绑定了的网站或者其他的网页,只要你在其中一个地方登录了,另一个地方便会自动的登录,这样的话用户的体验便大大的增强了。
今天我们就来做一做简单的单点登录的案例。我们主要用的就是ssm了,由于是简单的案例,我们这里也就不用数据库了。具体的依赖或是jar还有想应的配置文件自己自行的导入即可,就不在这里做过多的强调了。
下面便是我们登录的前台页面了。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <html> <head> <title>登录</title> </head> <body> <form action="<%= basePath%>user/login" method="post"> <span>用户名:</span><input type="text" name="username"/> <span>密 码</span><input type="password" name="password"/> <input type="hidden" name="gotoUrl" value="${gotoUrl}"> <input type="submit"/> </form> </body> </html>
其中有个gotoUrl的值先在这里卖个关子,后面再告诉大家里面的玄机。其他的相信大家都不陌生了,就是提供一个from表单和对应用户的用户名和密码。
就下来就需要写一个登录的控制器了
@PostMapping("/login") public String log(String username,String password,String gotoUrl,HttpServletResponse response){ boolean ok = SSOCheck.checkLogin(username,password); if(ok){ Cookie cookie = new Cookie("ssocookie","sso"); cookie.setPath("/"); response.addCookie(cookie); return gotoUrl; } return null; }
将对应的from表单里面的值传入进去。其中有个工具类,里面有个checkLogin的方法,因为这只是一个小小的案例,所以这个方法只是提供了一个写死的用户名和密码。具体代码如下:
private static final String USERNAME = "user"; private static final String PASSWORD = "123"; public static boolean checkLogin(String username,String password){ if(username.equals(USERNAME) && password.equals(PASSWORD)){ return true; } return false; }
就是当你的用户名是user时和密码是123时你才可以登录成功,相信这个大家很容易理解。
当我们登录成功的时候这个方法会返回一个Boolean值true,这个时候我们就会将会像cookie里面写入一个密令(这个时候就相当于我们在景点买了一个全票)。最后返回你想要登录的页面。
下面的分别是第一个页面登录后的主页以及第二个页面登录后的主页
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>欢迎访问DEMO1</title> </head> <body> <h1>这个是DEMO1的主页</h1> </body> </html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>欢迎访问DEMO2</title> </head> <body> <h1>这个是DEMO2的主页</h1> </body> </html>
里面的结构很简单,只是里面的标题和正文有些区别而已。当我们直接访问这两个页面的时候便会先判断用户是否登录了,如果没有登录的话就跳转到登录界面。这个时候之前卖关子的地方便出来了,这个时候gotoUrl便派上了用场,这个是用来记录你本来要去哪个页面的地址,就是你本来是要去success1这个页面的,但是你没有登录,当你登录成功的时候自然是跳转回来success1这个页面,而这个时候gotoUrl就会告诉你要跳转到相应的页面,如果没有这个的话,你都不知道页面要往哪个页面跳转。接下来的便是对应的后台控制器的代码了。
@GetMapping("/demo1") public String demo1(HttpServletRequest request){ if(SSOCheck.checkCookie(request)){ return "success1"; } request.getSession().setAttribute("gotoUrl","success1"); return "login"; }
这里面也有一个工具类里的方法,它的作用是检测你是否有之前的密令(也就是你是否有全票),具体代码如下:
public static boolean checkCookie(HttpServletRequest request){ Cookie[] cookies = request.getCookies(); if(cookies!=null){ for (Cookie cookie:cookies){ if(cookie.getName().equals("ssocookie") && cookie.getValue().equals("sso")){ return true; } } } return false; }
该方法的返回值也是Boolean值,如果拿到了密令就会返回相应的页面,若是没有拿到密令的话也就是你没有登录或者是登录失效了(要知道默认的cookie你30分钟内你没有进行任何操作它是会失效的),这个时候就会把你要去对应页面的地址放在gotoUrl里面,然后跳到登录页面进行登录。
下面的代码是第二个网页的跳转
@GetMapping("/demo2") public String demo2(HttpServletRequest request){ if(SSOCheck.checkCookie(request)){ return "success2"; } request.getSession().setAttribute("gotoUrl","success2"); return "login"; }
里面的逻辑基本上是和第一个相同,只是修改跳转对应的页面。
基本上我们这个简单的单点登录案例到这里就结束了,下面我把完整的控制层代码以及工具类的代码给出来。
package com.itds.controller; import com.itds.util.SSOCheck; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
/** * @author tb * @ClassName LogConreoller * @description 登录控制器 * @DATE 2018/12/10 0010 09:31 **/ @Controller @RequestMapping("/user") public class LogConreoller { @PostMapping("/login") public String log(String username,String password,String gotoUrl,HttpServletResponse response){ boolean ok = SSOCheck.checkLogin(username,password); if(ok){ Cookie cookie = new Cookie("ssocookie","sso"); cookie.setPath("/"); response.addCookie(cookie); return gotoUrl; } return null; } @GetMapping("/demo1") public String demo1(HttpServletRequest request){ if(SSOCheck.checkCookie(request)){ return "success1"; } request.getSession().setAttribute("gotoUrl","success1"); return "login"; } @GetMapping("/demo2") public String demo2(HttpServletRequest request){ if(SSOCheck.checkCookie(request)){ return "success2"; } request.getSession().setAttribute("gotoUrl","success2"); return "login"; } }
package com.itds.util; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; /** * @author tb * @ClassName SSOCheck * @description 验证工具类 * @DATE 2018/12/7 0007 15:57 **/ public class SSOCheck { private static final String USERNAME = "user"; private static final String PASSWORD = "123"; public static boolean checkLogin(String username,String password){ if(username.equals(USERNAME) && password.equals(PASSWORD)){ return true; } return false; } public static boolean checkCookie(HttpServletRequest request){ Cookie[] cookies = request.getCookies(); if(cookies!=null){ for (Cookie cookie:cookies){ if(cookie.getName().equals("ssocookie") && cookie.getValue().equals("sso")){ return true; } } } return false; } }
下面就是最后测试阶段了。对应的效果图如下:
注意看两个页面的地址栏。
由于这个时候没有登录所以都是显示的让你登录,那么我们就随便在其中页面上进行登录。登录后效果:
这个时候第一个页面已经是登录了的,而第二个页面还是需要我们进行登录,这个时候我们只需要对第二个页面进行刷新即可看到效果。
这个时候我们可以对比下第一个网页的地址栏就知道第二个网页是刷新后的结果了。
此篇文章由DurkBlue发布,麻烦转载请注明来处