实现多客户端的单点登录。一次登录,多个客户端不用登录。
http://client1.com:8081/employees
http://client2.com:8082/boss
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.gulimall</groupId>
<artifactId>common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
server.port=8081
spring.application.name=client1.com
sso.server.url=http://ssoserver.com:8080/login.html
//无需登录就可访问
@ResponseBody
@GetMapping("/hello")
public String hello() {
return "hello";
}
@Controller
public class HelloController {
@Value("${sso.server.url}")
String ssoserverUrl;
@Value("${spring.application.name}")
String serverName;
@Value("${server.port}")
String port;
//登录后才可访问
//token:令牌,登录成功才有,required = false
/**
@Model:保存页面数据
@session:获取session的数据
@token:去ssoserver服务器登录成功跳回来后带上
*/
@GetMapping("/employees")
public String employees(Model model, HttpSession session,
@RequestParam(value = "token",required = false) String token) {
if (!StringUtils.isEmpty(token)){
//todo 去ssoserver获得真正的数据与token进行判断,数据一致才放入session, ok
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> forEntity = restTemplate.getForEntity("http://ssoserver.com:8080/userInfo?token=" + token, String.class);
String body = forEntity.getBody();
session.setAttribute("loginUser",body);
}
Object loginUser = session.getAttribute("loginUser");
//判断session是否有值,有值说明登录
if (loginUser == null) {
//未登录,跳转到登录服务器。http://ssoserver.com:8080/login.html.服务名称、端口号可以注入进来@Value
//登录成功后再跳回来,redirect_url=http://client1.com:8081/employees
return "redirect:" + ssoserverUrl+"?redirect_url=http://"+serverName+":"+port+"/employees";
} else {
//已经登录
List<String> emps = new ArrayList<>();
emps.add("张三");
emps.add("李四");
emps.add("王五");
emps.add("赵刘");
model.addAttribute("emps", emps);
return "list";
}
}
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>员工列表。title>
head>
<body>
<h1>欢迎,[[${session.loginUser}]]h1>
<ul>
<li th:each="emp:${emps}">姓名:[[${emp}]]li>
ul>
body>
html>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
server.port=8080
sso.server.url=http://ssoserver.com:8080/login.html
#配置redis
spring.redis.host=192.168.56.10
spring.redis.port=6379
@Controller
public class LoginController {
@Value("${sso.server.url}")
String ssoserverUrl;
@Autowired
RedisTemplate redisTemplate;
//去登陆页
/**
* redirect_url:重定向地址
* sso_token:不一定有,登录才有,required = false
* */
@GetMapping("/login.html")
public String loginPage(@RequestParam("redirect_url") String redirect_url, Model model,
@CookieValue(value = "sso_token",required = false) String sso_token) {
if (!StringUtils.isEmpty(sso_token)){
//如果不为空说明有人登陆过,给浏览器留下了痕迹
return "redirect:"+redirect_url+"?token="+sso_token;
}
model.addAttribute("redirect_url", redirect_url);
return "login";
}
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>登录页title>
head>
<body>
<form action="/login" method="post">
用户名:<input name="username">br>
密 码:<input type="password" name="password">br>
<input type="hidden" name="redirect_url" th:value="${redirect_url}">
<input type="submit" value="登录">
form>
body>
html>
//登录
@PostMapping("/login")
public String login(@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestParam("redirect_url") String redirect_url,
HttpServletResponse response) {
if (!StringUtils.isEmpty(username)&&!StringUtils.isEmpty(password)){
System.out.println("登录成功");
//登陆成功,跳转到之前的页面,http://client1.com:8081/employees,
// 把登录成功的session放入redis
String uuid = UUID.randomUUID().toString().replace("-","");
redisTemplate.opsForValue().set(uuid,username);
Cookie sso_token = new Cookie("sso_token",uuid);
response.addCookie(sso_token);
return "redirect:"+redirect_url+"?token="+uuid;
}else {
System.out.println("登录失败");
//登录失败,跳回login.html
return "login";
}
}
//获取用户信息
@ResponseBody
@GetMapping("/userInfo")
public String userInfo(@RequestParam("token") String token){
String s = (String) redisTemplate.opsForValue().get(token);
return s;
}