单点登录原理介绍

传统方式登录问题

说明:如果采用SESSION的方式实现登录操作,由于nginx负载均衡的策略,用户可以访问不同的服务器,但是SESSION不能共享,所以导致用户频繁登录,体验不好。
image.png

SSO

单点登录(Sing了SignOn,SSO)就是通过用户的一次性鉴别登录,当用户在身份认证服务器上登录一次后,即可获得访问单点登录系统中其他管理系统和应用软件的权限。同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是目前比较流行的。

项目单点登录设计

image.png
实现步骤:
1.当用户输入用户名和密码点击登录时,将请求发给WEB消费者服务器。
2.WEB服务器将用户信息传递给SSO单点登录系统完成数据校验。
3.如果登录成功,则动态生成密匙信息,将user数据转化为json,保存在redis中,注意超时时间的设定。
4.SSO将登录的凭证传给WEB服务器。
5.WEB服务器将用户密匙TICKET信息保存到用户的cookie中,注意超时时间设定。
6.如果登录不成功,则直接返回错误信息即可。

用户单点登录实现

页面url分析

image.png

页面参数分析

image.png

页面JS分析

image.png

编辑UserController

/**
 * 完成登录操作:
 *      1.url地址:http://www.jt.com/user/doLogin?r=0.2054949537866282
 *      2.参数:用户名和密码username,password。
 *      3.返回值结果:Sysresult
 *Cookie使用:
 *      1.创建Cookie
 *          Cookie cookie=new Cookie("名字",ticket);
 *      2.setpath("/"):path表示如果需要获取cookie中的数据,则url地址所在路径设定
 *      3.setDomian("xxxxx"):设定cookie共享的域名地址,是实现单点登录必备的要素!
 * 通过response对象发送cookie到客户端中
 */
@RequestMapping("/doLogin")
@ResponseBody
public SysResult doLogin(User user, HttpServletResponse response){
    String ticket=userService.doLogin(user);
    if(StringUtils.isEmpty(ticket)){
        //说明用户名和密码错误
 return SysResult.fail();
    }else{
        /*//创建Cookie这种写法比较繁琐,所以利用cookie工具API
 Cookie cookie=new Cookie("JT_TICKET", ticket); cookie.setMaxAge(7*24*60*60);//设定cookie存活有效期
 cookie.setPath("/");//设定cookie有效范围
 cookie.setDomain("jt.com");//设定cookie共享的域名
 response.addCookie(cookie);*/ //利用cookie工具API
 CookieUtil.addCookie(response, "JT_TICKET", ticket, 7*24*60*60,"jt.com" );
        return SysResult.success();//表示用户登录成功
 }
}

编辑UserService

/**
     * 1.获取用户信息校验数据库中是否有记录
     * 2.有  开始执行单点登录流程
     * 3.没有 直接返回null即可
     * @param user
     * @return
     */
    @Override
    public String doLogin(User user) {  //username/password
        //1.将明文加密
        String md5Pass =
                DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
        user.setPassword(md5Pass);
        QueryWrapper queryWrapper = new QueryWrapper<>(user);
        //根据对象中不为null的属性当做where条件.
        User userDB = userMapper.selectOne(queryWrapper);
        if(userDB == null){
            //用户名或密码错误
            return null;
        }else{ //用户名和密码正确  实现单点登录操作
            String ticket = UUID.randomUUID().toString();
            //如果将数据保存到第三方 一般需要脱敏处理
            userDB.setPassword("123456你信不??");
            String userJSON = ObjectMapperUtil.toJSON(userDB);
            jedisCluster.setex(ticket, 7*24*60*60, userJSON);
            return ticket;
        }
    }

页面效果展示

image.png

你可能感兴趣的:(java)