cookie+session(这里使用redistemplate代替)实现单点登录流程

发布时间 2023-07-25 23:54:24作者: 你就学个JVAV?

 

  1. user发起资源请求(带上回调的路径方便回调),通过判断是否浏览器的cookie中是否存在登录过的痕迹,比如有人登了,然后存了一个cookie到浏览器

  2. 如果拿到了cookie是有东西的,则带上这个cookie的内容返回给client,如果没有东西,则继续登录,向session中存入userInfo,并给浏览器设置cookie

  3. 另一个相信任的应用再发起资源请求的时候会发现已经被登录过了,直接去session中拿出信息然后回显就完事了

 

sso-server

controller

 @Controller
 public class LoginController {
 ​
 ​
     static String redirect_url;
 ​
     /**
      * 跳转到登录页面
      * @param redirect_url
      * @return
      */
     @GetMapping(value = "/login.html")
     public String toLogin(@RequestParam(value = "redirect_url") String redirect_url,
                           @CookieValue(value = "sso_token",required = false) String token){
 ​
         // 如果token不为空,表示有人登录过,其他授信应用也可以直接登陆
         if(!StringUtils.isEmpty(token)){
             System.out.println("token: " + token);
             return "redirect:"+LoginController.redirect_url + "?token="+token;
         }
 ​
 ​
         LoginController.redirect_url = redirect_url;
         return "login";
     }
 ​
     @Resource
     private RedisTemplate<String,String> redisTemplate;
 ​
     @PostMapping(value="/dologin")
     public String doLogin(@RequestParam(value = "username") String username,
                           @RequestParam(value = "password") String password,
                           HttpServletResponse response,
                           @CookieValue(value = "sso_token",required = false) String token) {
         // 登录成功的逻辑
         if(!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)){
             UserVo userVo = new UserVo();
             userVo.setUsername(username);
             userVo.setPassword(password);
 ​
             System.out.println("userVo = " + userVo);
             String uuid = createUUID();
 ​
             // 将token令牌保存到cookie中
             Cookie cookie = new Cookie("sso_token", uuid);
             response.addCookie(cookie);
             System.out.println("设置token成功cookie");
             // store to redis to save
             redisTemplate.opsForValue().set(uuid,userVo.getUsername());
 ​
             System.out.println("redirect_url = " + LoginController.redirect_url);
 ​
 //          将token拼接上,一同返回给client让他们存到redis
             String url = LoginController.redirect_url + "?token=" + uuid;
             return "redirect:"+url;
         }
         // 登录失败 to login
         return "login";
     }
     public String createUUID(){
         return UUID.randomUUID().toString().replace("-", "");
     }
 ​
 }
 ​

sso-client

controller

 @Controller
 public class HelloController {
 ​
     @Value(value = "${sso.server.url}")
     String ssoServerUrl;
 ​
     @ResponseBody
     @GetMapping(value = "/hello")
     public String hello() {
         return "hello page";
     }
 ​
     @Resource
     RedisTemplate<String,String> redisTemplate;
 ​
     @GetMapping(value = "/users")
     public String usersInfo(HttpSession session,
                             @RequestParam(value = "token",required = false) String token,
                             Model model) {
         /**
          * 表示返回的时候带上了,带上了就表示登录成功了
          */
         if(!StringUtils.isEmpty(token)){
 ​
 ​
             System.out.println("client1 token = " + token);
 ​
             String userInfo = redisTemplate.opsForValue().get(token);
             System.out.println("userInfo = " + userInfo);
 ​
             model.addAttribute("username",userInfo);
             return "list";
         } else {
             String suffixUrl = "?redirect_url=http://client2.com:8092/users";
             // 远程登录验证 sso - server
             return "redirect:"+ssoServerUrl + suffixUrl;
         }
 ​
 }
 ​