有四个系统:
sso-main 首页系统 sso-cart 购物车系统 sso-vip vip系统 sso-login 登录系统
1、建一个maven管理的父子依赖项目
2、逻辑说明
首次登录情况: (1)无论要访问哪一个系统,都需要先登录,也就是需要先请求访问 登录系统sso-login。 (2)访问sso-login登录系统时,记得带上 来源系统的地址,这样就知道到底是从哪个系统请求来的。
<span> <a th:if="${session.loginUser == null}" href="http://login.codeshop.com:9000/view/login?target=http://www.codeshop.com:9010/view/index">登录</a> </span>
(3)提交用户信息表单请求之后,判断用户名密码是否存在,不存在则跳转回登录页面,如果存在,那么生成token,生成方式自定义,这里采用 UUID.randomUUID().toString(),然后设置cookie的域名,将token存放到cookie中,并将token和用户信息缓存到map中,然后重定向到目标页面
String token = UUID.randomUUID().toString(); Cookie cookie = new Cookie("TOKEN",token); cookie.setDomain("codeshop.com"); response.addCookie(cookie); LoginCache.loginUser.put(token,user);
//缓存map public class LoginCache { public static Map<String, User> loginUser = new HashMap<>(); }
(4)登录系统sso-login 还需要提供一个对外接口,根据token获取用户信息,方便子系统获取用户信息
@GetMapping("info") @ResponseBody public ResponseEntity<User> getUserInfo(String token){ if (!StringUtils.isEmpty(token)){ User user = LoginCache.loginUser.get(token); return ResponseEntity.ok(user); }else{ return new ResponseEntity<>(HttpStatus.BAD_REQUEST); } }
(5)提交用户信息成功之后,重定向目标页面,比如sso-main,这个时候,会先判断cookie是否为空,是否包含token,如果包含,那么根据token远程调用接口,获取用户信息,并将用户信息存入session中
@Autowired private RestTemplate restTemplate; private final String LOGIN_INFO_ADDRESS = "http://login.codeshop.com:9000/login/info?token="; @GetMapping("/index") public String toIndex(@CookieValue(required = false,value = "TOKEN") Cookie cookie, HttpSession session){ if (cookie != null){ String token = cookie.getValue(); if (!StringUtils.isEmpty(token)){ Map map = restTemplate.getForObject(LOGIN_INFO_ADDRESS + token, Map.class); session.setAttribute("loginUser",map); } } return "index"; }
(6)打开目标页面,从session中获取用户信息,判断是否为登录,
<h1>欢迎来到main code shop</h1> <span> <a th:if="${session.loginUser == null}" href="http://login.codeshop.com:9000/view/login?target=http://www.codeshop.com:9010/view/index">登录</a> <a th:unless="${session.loginUser == null}" href="#">退出</a> </span> <p th:unless="${session.loginUser == null}"> <span style="color: deepskyblue;" th:text="${session.loginUser.username}"></span> 已登录 </p> </body> </html>
3、非首次登录
(1)当需要访问sso-main主系统页面时,会先判断cookie是否为空,不为空,取出token,根据token调用外部接口,获取用户信息,直接登录
在这里插入代码片
public class ViewController { @Autowired private RestTemplate restTemplate; private final String LOGIN_INFO_ADDRESS = "http://login.codeshop.com:9000/login/info?token="; @GetMapping("/index") public String toIndex(@CookieValue(required = false,value = "TOKEN") Cookie cookie, HttpSession session){ if (cookie != null){ String token = cookie.getValue(); if (!StringUtils.isEmpty(token)){ Map map = restTemplate.getForObject(LOGIN_INFO_ADDRESS + token, Map.class); session.setAttribute("loginUser",map); } } return "index"; } }
最后总结
1、必须要设置cookie的domain域名值
2、host文件中映射的域名要一致
127.0.0.1 www.codeshop.com 127.0.0.1 vip.codeshop.com 127.0.0.1 cart.codeshop.com 127.0.0.1 login.codeshop.com