初识单点登录

单点登录

核心

  1. 登录成功,登录服务器生成token和对应用户信息以KV形式保存在reids中,并且留下登陆过的标记(Cookie:可以用token充当这个cookie)
  2. 后续还有其他客户服务器要判定登录时来到登录服务器,发现还有登录过的标记(这个Cookie就是token)就将这个token返回给对应客户服务器
  3. 然后这个客户服务器携带这个token来登录服务器(或redis中)查询对应信息
    • 如果查询的出来,说明登录过,将用户信息保留在客户服务器session中,通过认证
    • 如果查询不出来,说明验证未通过,继续重定向到登录服务器去登录

登录服务器核心代码

@Controller
public class SSOServerController {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * 客户服务器使用token来登录服务器查询对应信息请求
     *
     * @param token
     * @return
     */
    @ResponseBody
    @GetMapping("/userInfo")
    public String userInfo(@RequestParam("token") String token) {
        //3.然后这个客户服务器携带这个token来登录服务器查询对应信息
        return stringRedisTemplate.opsForValue().get(token);
    }

    @GetMapping("/login.html")
    public String loginPage(@RequestParam("redirect_url") String url
            , Model model
            , @CookieValue(value = "ssoToken", required = false) String ssoToken) {
        //2.后续还有其他客户服务器要判定登录时来到登录服务器,发现还有登录过的标记(这个Cookie就是token)就将这个token返回给对应客户服务器
        if (!StringUtils.isEmpty(ssoToken)) {
            return "redirect:" + url + "?token=" + ssoToken;
        }

        model.addAttribute("url", url);
        return "login";
    }

    @PostMapping("/SSOLogin")
    public String login(@RequestParam("username") String username
            , @RequestParam("password") String password
            , @RequestParam("url") String url
            , HttpServletResponse response) {
        //1.登录成功,登录服务器生成token和对应用户信息以KV形式保存在reids中,并且留下登陆过的标记(Cookie:可以用token充当这个cookie)
        if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
            //生成token 保存在redis
            String token = UUID.randomUUID().toString();
            stringRedisTemplate.opsForValue().set(token, username + password, 30L, TimeUnit.MINUTES);

            //生成cookie留下印记
            //如果再次来到登录页还有这个cookie说明已经登录过
            Cookie cookie = new Cookie("ssoToken", token);
            response.addCookie(cookie);

            return "redirect:" + url + "?token=" + token;
        }
        return "redirect:http://sso.com:8080/login.html";
    }
}

客户服务器核心代码

@Controller
public class SSOClientController {

    @Value("${sso.server.url}")
    private String SSOServer;

    @ResponseBody
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }

    @GetMapping("/list")
    public String list(HttpSession session, Model model, @RequestParam(value = "token", required = false) String token) {
        //token不为空说明 登录过,再去登录服务器查询对应token信息并验证,成功则将信息保存在当前服务器的session中,否则重定向到登录服务器
        if (token != null) {
            //3.然后这个客户服务器携带这个token来登录服务器查询对应信息
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> forEntity = restTemplate.getForEntity("http://sso.com:8080/userInfo?token=" + token, String.class);
            String loginUser = forEntity.getBody();
            //如果没查到对应信息,说明token不正确
            if (!StringUtils.isEmpty(loginUser)){
                session.setAttribute("loginUser", loginUser);
            }
        }

        //
        if (session.getAttribute("loginUser") == null) {
            return "redirect:" + SSOServer + "?redirect_url=http://client1.com:8081/list";
        } else {
            List<String> list = Arrays.asList("芜湖", "起飞", "这波", "不亏");
            model.addAttribute("list", list);
            return "list";
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值