通过cookie来实现单点登录

1.单点登录的流程

cookie是用来在客户端存储数据的工具、
在其中一个子系统登录,跳转到登录系统,登陆系统登陆完成,完成登录后会向发起登录的子系统写入一个cookie,保存用于认证用户是否登录的信息(token),其他子系统向服务器发起请求的时候,携带这个cookie完成登录。
cookie的域要是所有子系统相同的域,这样所有子系统才能访问到这个cookie。

2.单点登录流程图

在这里插入图片描述

2.单点登录的编码(部分核心代码)

代码链接:https://gitee.com/yuehewei/sso-single-sign-on

@Controller
@RequestMapping("/login")
public class LoginController {

    //模拟数据库数据
    private static Set<User> dbUsers;
    static {
        dbUsers=new HashSet<>();
        dbUsers.add(new User(0,"yuehwi","123456"));
        dbUsers.add(new User(1,"yueei1","1234567"));
        dbUsers.add(new User(2,"yueei2","12345"));
        dbUsers.add(new User(3,"yueei3","1234"));
        dbUsers.add(new User(4,"yueh4","123"));

    }
@PostMapping
   public  String doLogin(User user, HttpSession session, HttpServletResponse response){
       Object target = session.getAttribute("target");
       //判读这个用户是否存在
       Optional<User> user1 = dbUsers.stream().filter(dbUsers -> dbUsers.getUsername().equals(user.getUsername()) &&
               dbUsers.getPassword().equals(user.getPassword())

       ).findFirst();

       /*
        * 1.当这个用户存在,我们需要给他生成一个随机的uuid作为token
        * 2.并把token作为key,user作为value,存在缓存中
        * 3.并把token交割cookie,并设置该cookie可跨域的域名
        * 4.将cookie返还给客户端
        */
       if (user1.isPresent()){
           String token = UUID.randomUUID().toString();
           LoginCacheUtil.loginMap.put(token,user1.get());
           Cookie cookie = new Cookie("TOKEN",token);
           //跨域共享cookie的方法:setDomain()
           cookie.setDomain("codeshop.com");
           response.addCookie(cookie);
       }else {
           session.setAttribute("msg","用户名或者密码错误");

           return "login";
       }
       return "redirect:"+target;

   }
    @GetMapping("info")
    @ResponseBody
    /*
     *功能描述
     * 得到token,并在缓存中找到key=token的用户并返回
     */
    public ResponseEntity<User> getUserInfo(String token){
        if (!StringUtils.isEmpty(token)){
            User user = LoginCacheUtil.loginMap.get(token);
            return ResponseEntity.ok(user);
        }else {
            return new ResponseEntity<>(null, HttpStatus.BAD_REQUEST);
        }


    }

}
@Controller
@RequestMapping("view")
public class ViewController {
    @Autowired
    //RestTemplate 是从 Spring3.0 开始支持的一个 HTTP 请求工具,它提供了常见的REST请求方案的模版
    RestTemplate restTemplate;

    private  final  String LOGIN_INFO="http://login.codeshop.com:9000/login/info?token=";
    @GetMapping ("index")
    public String toIndex(@CookieValue(required = false,value = "TOKEN") Cookie cookie, HttpSession session){
         //判断用户是否登陆过,RestTemplate 发送的是Http请求,getForObject 的返回值就是服务提供者返回的数据,使用getForObject 无法获取到响应头
        if ( cookie!=null){
            String token = cookie.getValue();
            if (!StringUtils.isEmpty(token)){
                Map user = restTemplate.getForObject(LOGIN_INFO +token, Map.class);
               session.setAttribute("loginUser",user);
            }

        }

        return "index";
    }
}

参考视频链接:https://space.bilibili.com/342321610

Logo

Authing 是一款以开发者为中心的全场景身份云产品,集成了所有主流身份认证协议,为企业和开发者提供完善安全的用户认证和访问管理服务

更多推荐