关于单点登录:单点登录

35次阅读

共计 3627 个字符,预计需要花费 10 分钟才能阅读完成。

概念

单点登录 (SingleSignOn,SSO),就是通过用户的一次性甄别登录。 当用户在身份认证服务器上登录一次当前,即可取得拜访单点登录零碎中其余关联系统和应用软件的权限,这种形式缩小了由登录产生的工夫耗费,辅助了用户治理,是目前比拟风行的 一种登录形式

业务场景

要求用户只须要登录一次, 那么就能够拜访其余的认证零碎, 无需用户再次登录.
如果登录信息都保留在各自的服务器上, 则必然会呈现用户频繁登录的景象.

单点登录实现策略

步骤:
1. 当用户输出用户名和明码时须要将数据传递给 jt-web 服务器进行登录操作.
2.jt-web 服务器须要将数据传到 jt-sso 服务器中进行数据的校验.
3.jt-sso 依据 username/password 查询数据库校验数据是否无效.
4. 如果用户名和明码正确则将数据通过解决之后保留到 redis 中 KEY=UUID(每次生成的都不一样) VALUE=“userJSON”
5. 如果用户写入 redis 胜利, 之后须要将用户的登录的凭证返回给客户端.
6.JT-WEB 服务器将获取的 TICKET 信息保留到客户端的 Cookie 中, 不便下次应用. 并且要求 cookie 共享 的.

cookie

因为不能将信息存在服务器的 session 中, 所以 cookie 就是单点登录实现的要害.

概念

  1. Cookie 是将会话中产生的数据保留在客户端,是客户端技术。
  2. Cookie 是基于两个头进行工作的:别离是 Set-Cookie 响应头和 Cookie 申请头
  3. 通过 Set-Cookie 响应头将 cookie 从服务器端发送给浏览器,让浏览器保留到外部;而浏览器一旦保留了 cookie,当前浏览器每次拜访服务器时,都会通过 cookie 申请头,将 cookie 信息再带回服务器中。在须要时,在服务器端能够获取申请中的 cookie 中的数据,从而实现某些性能。

cookie API

1. 创立 Cookie 对象

Cookie c = new Cookie(String name, String value);
// 创立 cookie 的同时须要指定 cookie 的名字和 cookie 要保留的值
// Cookie 的名字一旦指定后,就无奈批改!

2. 将 Cookie 增加到 response 响应中

response.addCookie(Cookie c);
// 将 cookie 增加到响应中,由服务器负责将 cookie 信息发送给浏览器,再由浏览器保留到外部(能够屡次调用该办法,增加一个以上的 cookie)

3. 获取申请中的所有 cookie 对象组成的数组

Cookie[] cs = request.getCookies();
// 获取申请中携带的所有 cookie 组成的 cookie 对象数组,如果申请中没有携带任何 cookie,调用该办法会返回 null。

4. 删除浏览器中的 Cookie
cookie 的 API 中没有提供间接删除 cookie 的办法,能够通过别的形式间接删除 cookie
删除名称为 cart 的 cookie:能够向浏览器再发送一个同名的 cookie(即名称也叫做 cart),并设置 cookie 的最大生存工夫为零,因为浏览器是依据 cookie 的名字来辨别 cookie,如果前后两次向浏览器发送同名的 cookie,后发送的 cookie 会笼罩之前发送的 cookie。而后发送的 cookie 设置了生存工夫为零,因而浏览器收到后也会立刻删除!

// 创立一个名称为 cart 的 cookie
Cookie c = new Cookie("cart", "");
// 设置 cookie 的最大生存工夫为零
c.setMaxAge(0);
// 将 cookie 增加到响应中, 发送给浏览器
response.addCookie(c);
out.write("胜利删除了名称为 cart 的 cookie...");

5.Cookie 的罕用办法

cookie.getName(); // 获取 cookie 的名字
cookie.getValue(); // 获取 cookie 中保留的值
cookie.setValue(); // 设置 / 批改 cookie 中保留的值(没有 setName 办法, 因为 cookie 的名字无奈批改)
cookie.setMaxAge(); // 设置 cookie 的最大生存工夫(如果不设置,cookie 默认在一次会话完结时销毁!)

6.setMaxAge 办法 :设置 cookie 的最大生存工夫
如果不设置该办法,cookie 默认是会话级别的 cookie,即生存工夫是一次会话。当浏览器敞开,会话完结时,cookie 也会被销毁(cookie 默认存在浏览器的内存中,当浏览器敞开,内存开释,cookie 也会随着内存的开释而销毁。)
如果设置了该办法,cookie 将不会保留到浏览器的内存中,而是以文件模式保留到浏览器的长期文件夹中(也就是硬盘上),这样再敞开浏览器,内存开释,保留到硬盘上的 cookie 文件不会销毁,再次关上浏览器,还能够获取硬盘上的 cookie 信息。

实例

前端 controller 层

/**
 * 实现用户的登录操作
 * url 地址:http://www.jt.com/user/doLogin?r=0.8989367429030823
 * 参数:   username/password
 * 返回值: SysResult 对象  的 JSON 的数据.
 *
 *  cookie.setMaxAge(-1);  敞开浏览器会话时删除
 *  cookie.setMaxAge(0);   立刻删除 cookie
 *  cookie.setMaxAge(100); cookie 能够存储的工夫单位是秒
 *
 *  http://www.jt.com/saveUser/xxx
 *  cookie.setPath("/");
 *  cookie.setPath("/add");
 */
 @RequestMapping("/doLogin")
 @ResponseBody
 public SysResult doLogin(User user, HttpServletResponse response){
     //1. 实现用户的登录操作!!!
     String ticket = dubboUserService.doLogin(user);
     //2. 校验 ticket 是否有值.
     if(StringUtils.isEmpty(ticket)){
         // 用户名或者明码谬误
         return SysResult.fail();}
     //3. 如果用户的 ticket 不为 null, 则示意登录正确, 须要将数据保留到 cookie 中
     //Cookie 要求   1.7 天无效  2. 要求 cookie 能够在 jt.com 的域名中共享  3.cookie 权限 /
     Cookie cookie = new Cookie("JT_TICKET",ticket);
     cookie.setMaxAge(7*24*3600);
     cookie.setDomain("jt.com"); // 在 jt.com 中实现页面共享.
     cookie.setPath("/");        // 定于 cookie 的权限根目录无效
     response.addCookie(cookie); // 利用 response 将 cookie 保留到客户端中.
     return SysResult.success();}

后端 service 实现类

 /**
 * 1. 依据用户名和明码查询数据库
 * 2. 校验用户数据的有效性.
 * 3. 如果用户的数据是正确的 则开始进行单点登录操作.
 * 4. 如果用户数据不正确 则 ticket 数据为 null 即可.
 * @param user
 * @return
 */
@Override
public String doLogin(User user) {

    //1. 将明码进行加密解决
    String password = DigestUtils.md5DigestAsHex(user.getPassword().getBytes());
    user.setPassword(password);
    // 如果传递的是对象, 则依据对象中不为 null 的属性充当 where 条件
    QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
    User userDB = userMapper.selectOne(queryWrapper);
    //2. 校验数据是否无效
    if(userDB == null){return null;}
    //userDB 数据不为 null, 用户的输出信息正确. 开启单点登录操作.
    //3.1 动静生成 uuid
    String ticket = UUID.randomUUID().toString().replace("-", "");
    //3.2 脱敏解决
    userDB.setPassword("123456 你信不??");
    String userJSON = ObjectMapperUtil.toJSON(userDB);
    //3.3 将数据保留到 redis 中
    jedisCluster.setex(ticket, 7*24*60*60, userJSON);
    return ticket;
}

前后端通过 dubbo 以及公共接口调用.

正文完
 0