单点登录
- 一处登陆 处处使用
环境配置
gulimall-test-sso-client
gulimall-test-sso-server
127.0.0.1 ssoserver.com
127.0.0.1 client1.com
127.0.0.1 client2.com
gulimall-test-sso-server 中设置登陆
@GetMapping("/login.html")
public String loginPage(@RequestParam("redirect_url") String url, Model model){
model.addAttribute("url",url);
return "login";
}
<form action="/doLogin" method="post">
用户名:<input type="text" name="username" /><br />
密码:<input type="password" name="password" /><br />
<input type="hidden" name="url" th:value="${url}"/><br />
<input type="submit" value="登录">
</form>
当登陆成功过
@PostMapping(value = "/doLogin")
public String doLogin(String username,String password,String url) {
if (!StringUtils.isEmpty(username)&&StringUtils.isEmpty(password)){
//登录成功跳转,跳回到登录页
return "redirect:"+url;
}
//登陆失败
return "login";
}
报错无法跳转回去
String uuid = UUID.randomUUID().toString().replace("_", "");
redisTemplate.opsForValue().set(uuid, username);
//登录成功跳转,跳回到登录页 并携带一个令牌uuid 返回出去
return "redirect:" + url + "?token=" + uuid;
在客户端中
// ssoserver登陆成功 之后 带回的token 不一定是会带回来的 设置required = false
public String employees(Model model, HttpSession session,
@RequestParam(value = "token", required = false) String token) {
if (!StringUtils.isEmpty(token)) {
// todo 去ssoserver 获取当前token对应用户真正信息
session.setAttribute("loginUser", "张三");
}
}
gulimall-test-sso-client
@GetMapping("/login.html")
public String loginPage(@RequestParam("redirect_url") String url, Model model) {
model.addAttribute("url", url);
return "login";
}
@PostMapping(value = "/doLogin")
public String doLogin(@RequestParam("username") String username, @RequestParam("password") String password,
@RequestParam("url") String url) {
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
//redis 中保存
String uuid = UUID.randomUUID().toString().replace("_", "");
redisTemplate.opsForValue().set(uuid, username);
//登录成功跳转,跳回到登录页 并携带一个令牌uuid 返回出去
return "redirect:" + url + "?token=" + uuid;
}
//登陆失败
return "login";
}
client1 登陆成功了 如果还有client2呢 解决方案 第二个系统不需要登录 复制一份client1 server 在一个客户端 登录之后 并没有记住 登陆过 所以第二个登录了 依旧跳转登录界面 所以给浏览器 留一个令牌(token)
//server 服务器
public String doLogin(@RequestParam("url") String url,HttpServletResponse response) {
Cookie cookie = new Cookie("sso_token",uuid);
//设置cookie
response.addCookie(cookie);
return "redirect:" + url + "?token=" + uuid;
---
}
登陆成功重定向和保存cookie 浏览器要给ssoserver.com斯名下保存一个cookie; 浏览器以后访问这个域名都要蒂上发个域名下的所有cookie
//客户端client2 登录 @CookieValue 取出cookie(不一定存在required = false)
@GetMapping("/login.html")
public String loginPage(@RequestParam("redirect_url") String url, Model model,
@CookieValue(value = "sso_token",required = false) String sso_token) {
if (!StringUtils.isEmpty(sso_token)){
///说明之前有人登录过,浏览器留下了痕迹 又重定向到 请求页面 并且 携带tocken
return "redirect:" + url + "?token=" + sso_token;
}
model.addAttribute("url", url);
return "login";
}
登录跳转成功之后 创建直接token
server
@Controller
public class LoginController {
@Autowired
StringRedisTemplate redisTemplate;
@ResponseBody
@GetMapping("userInfo")
public String userInfo(@RequestParam("token") String token){
String s = redisTemplate.opsForValue().get(token);
return s;
}
@GetMapping("/login.html")
public String loginPage(@RequestParam("redirect_url") String url, Model model,
@CookieValue(value = "sso_token",required = false) String sso_token) {
if (!StringUtils.isEmpty(sso_token)){
///说明之前有人登录过,浏览器留下了痕迹
return "redirect:" + url + "?token=" + sso_token;
}
model.addAttribute("url", url);
return "login";
}
@PostMapping(value = "/doLogin")
public String doLogin(@RequestParam("username") String username,
@RequestParam("password") String password,
@RequestParam("url") String url,
HttpServletResponse response) {
if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
//redis 中保存
String uuid = UUID.randomUUID().toString().replace("_", "");
redisTemplate.opsForValue().set(uuid, username);
//登录成功跳转,跳回到登录页 并携带一个令牌uuid 返回出去
Cookie cookie = new Cookie("sso_token",uuid);
response.addCookie(cookie);
return "redirect:" + url + "?token=" + uuid;
}
//登陆失败
return "login";
}
}
client1
@Controller
public class HelloController {
@Value("${sso.server.url}")
String ssoServerUrl;
@ResponseBody
@GetMapping(value = "/hello")
public String hello() {
return "hello";
}
@GetMapping(value = "/employees")
// ssoserver登陆成功 之后 带回的token 不一定是会带回来的 设置required = false
public String employees(Model model, HttpSession session,
@RequestParam(value = "token", required = false) String token) {
if (!StringUtils.isEmpty(token)) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> forEntity =
restTemplate.getForEntity("http://ssoserver.com:8080/userInfo?token=" + token, String.class);
String body = forEntity.getBody();
// todo 去ssoserver 获取当前token对应用户真正信息
session.setAttribute("loginUser", body);
}
Object loginUser = session.getAttribute("loginUser");
if (loginUser == null) {
//没登录,跳转到服务器登录 重定向到 新地址 并携带之前地址
//╱跳转过去以后,使用url上的查询参数标识我们自己是哪个页面
return "redirect:" + ssoServerUrl + "?redirect_url=http://client1.com:8081/employees";
} else {
List<String> emps = new ArrayList<>();
emps.add("张三");
emps.add("李四");
model.addAttribute("emps", emps);
return "list";
}
}
}
client2
@Controller
public class HelloController {
@Value("${sso.server.url}")
String ssoServerUrl;
@ResponseBody
@GetMapping(value = "/hello")
public String hello() {
return "hello";
}
@GetMapping(value = "/boss")
// ssoserver登陆成功 之后 带回的token 不一定是会带回来的 设置required = false
public String employees(Model model, HttpSession session,
@RequestParam(value = "token", required = false) String token) {
if (!StringUtils.isEmpty(token)) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> forEntity =
restTemplate.getForEntity("http://ssoserver.com:8080/userInfo?token=" + token, String.class);
String body = forEntity.getBody();
// todo 去ssoserver 获取当前token对应用户真正信息
session.setAttribute("loginUser", body);
}
Object loginUser = session.getAttribute("loginUser");
if (loginUser == null) {
//没登录,跳转到服务器登录 重定向到 新地址 并携带之前地址
//╱跳转过去以后,使用url上的查询参数标识我们自己是哪个页面
return "redirect:" + ssoServerUrl + "?redirect_url=http://client2.com:8082/boss";
} else {
List<String> emps = new ArrayList<>();
emps.add("张三");
emps.add("李四");
model.addAttribute("emps", emps);
return "list";
}
}
}