单点登录系统知识点总结

单点登录系统

单点登录要解决的核心问题是:一站点登录,多站点可以同时访问。 

单点登录业务流程

1. 登录页面,用户登录

2. 判断用户名和密码是否正确

3. 登录成功后通过uuid生成token,token相当于原来的jsessionid。

4. 把用户信息保存到redis中,key就是token,value就是用户对象转成的json。

5. 设置key的过期时间,模拟session的过期时间,一般为半个小时。

6. 将token写入Cookie。Cookie要绑定二级域名,实现跨域。

7. 将token及登录成功的结果响应给浏览器。

8. 浏览器弹出登录成功提示框,点击确定,页面跳转到首页

9. 在首页渲染的过程中,发送ajax请求给单点登录系统,服务端通过token获取到用户信息返回浏览器,浏览器端从返回的用户信息中获取到当前登录用户的用户名,显示到首页上。(这里会有js跨域问题,使用jsonp解决。Ajax跨域访问的时候,请求正常发过去了,服务端也把结果响应给浏览器,但是当Ajax要拿这个响应回来的数据的时候,浏览器不让拿。跨域的根在这。)

Service层

@Override

public e3Result login(String username, String password) {

// 1、判断用户名密码是否正确。

TbUserExample example = new TbUserExample();

Criteria criteria = example.createCriteria();

criteria.andUsernameEqualTo(username);

//查询用户信息

List<TbUser> list = userMapper.selectByExample(example);

if (list == null || list.size() == 0) {

return e3Result.build(400, "用户名或密码错误");

}

TbUser user = list.get(0);

//校验密码

if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {

return e3Result.build(400, "用户名或密码错误");

}

// 2、登录成功后生成token。Token相当于原来的jsessionid,字符串,可以使用uuid

String token = UUID.randomUUID().toString();

// 3、把用户信息保存到redis。Key就是token,value就是TbUser对象转换成json

// 4、使用String类型保存Session信息。可以使用“前缀:token”为key

user.setPassword(null);

jedisClient.set(USER_INFO + ":" + token, JsonUtils.objectToJson(user));

// 5、设置key的过期时间。模拟Session的过期时间。一般半个小时。

jedisClient.expire(USER_INFO + ":" + token, SESSION_EXPIRE);

// 6、返回e3Result包装token。

return e3Result.ok(token);

}

表现层

@RequestMapping(value="/user/login", method=RequestMethod.POST)

@ResponseBody

public e3Result login(String username, String password,

HttpServletRequest request, HttpServletResponse response) {

// 1、接收两个参数。

// 2、调用Service进行登录。

e3Result result = userService.login(username, password);

// 3、从返回结果中取token,写入cookie。Cookie要跨域。

String token = result.getData().toString();

CookieUtils.setCookie(request, response, COOKIE_TOKEN_KEY, token);

// 4、响应数据。Json数据。e3Result,其中包含Token。

return result;

 

}

 

根据token查询用户信息

Service层

@Override

public e3Result getUserByToken(String token) {

// 2、根据token查询redis

String json = jedisClient.get(USER_INFO + ":" + token);

if (StringUtils.isBlank(json)) {

// 3、如果查询不到数据。返回用户已经过期。

return e3Result.build(400, "用户登录已经过期,请重新登录。");

}

// 4、如果查询到数据,说明用户已经登录。

// 5、需要重置key的过期时间。

jedisClient.expire(USER_INFO + ":" + token, SESSION_EXPIRE);

// 6、把json数据转换成TbUser对象,然后使用e3Result包装并返回。

TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);

return e3Result.ok(user);

}

表现层

@RequestMapping("/user/token/{token}")

@ResponseBody

public e3Result getUserByToken(@PathVariable String token) {

e3Result result = userService.getUserByToken(token);

return result;

}

 

我想访问订单系统,在展示订单确认页面之前,需要对用户身份进行认证,要求用户必须登录。使用springmvc的拦截器实现。需要实现一个接口HandlerInterceptor接口。

业务流程如下:

1. 从Cookie中取token

2. 如果token为空,说明用户未登录,需要跳转到登录页面进行登录。在重定向到登录页面时,要将当前系统的url作为参数传过来,以便登录成功之后能再跳转到当前系统。

3. 如果token不为空,要调用单点登录系统中的服务,根据token验证用户信息是否存在

  如果不存在,说明用户登录已经过期,需要跳转到登录页面重新登录。在重定向到登录页面时,要将当前系统的url作为参数传过来,以便登录成功之后能再跳转到当前系统。

  如果存在,说明用户已经登录,根据当前用户的用户id查询订单信息,将结果数据返回给浏览器。

-------------------------------------------------------------------------------

  在集群环境下,如果用Session来存放用户的登录信息,那么会出现要求用户多次登录的情况.

  为解决这个问题,我们可以通过使用Session复制来解决,但是Session复制的使用会限制集群中服务器节点的数量,一旦集群中的服务器数量过多,集群的性能就会由高到低呈抛物线形式下滑。

  基于此,我们想着使用一个专门的Session服务器来统一管理Session,这样一来,集群中的节点数量就没有限制了。这个专门的Session服务器就是单点登录系统.

  单点登录系统使用redis模拟Session,实现Session的统一管理。

单点登录的业务流程如下:

1. 用户在登录页面进行登录,如果登录验证不成功,返回登录页面重新登录。

2. 登录成功后,服务端通过uuid随机生成一个名为token的字符串(相当于来的jsessionid),作为key值,并且将封装有当前登录用户信息的对象转成json字符串作为values值,以键值对的形式存入Redis缓存数据库。

3. 设置key的过期时间,一般设为半个小时。

4. 将token字符串写入Cookie中,返回给浏览器。在这个过程中,一般我们会同时响应一个重定向操作,让页面跳转到首页。

5. 在页面跳转到首页以后,我们有一个要求:就是要在首页上显示出当前登录用户的用户名。这个时候,我们采取的办法是在首页加载完毕之后,向单点登录系统发送一个ajax请求,请求的参数就是Cookie。

6. 单点登录系统接收到请求之后,取出Cookie里面存放的token字符串,去Redis中查找响应的用户信息,若查不到,会重定向到登录页面重新登录;若查到,会将用户信息由json字符串转成用户对象,并返给浏览器端。同时重设key的过期时间。

7. 浏览器拿到返回过来的用户对象,从中取出用户名,嵌入到首页的指定位置即可。注意:在这个过程中会产生一个跨域访问的问题。

什么是跨域问题?

答:域名不同或者域名相同端口号不同均可称为跨域。首页位置前台系统中,首页通过ajax请求访问单点登录系统,两个系统彼此独立,部署在不同的Tomcat服务器上,端口号不同,是跨域请求。跨域请求能发过去,并且浏览器能得到服务端返回的用户信息,但是ajax拿不到这个响应信息,浏览器不让使用。

如何解决跨域访问问题?

答:使用jsonp技术。

 

至此,登录成功!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值