一、什么是sso
SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一。
二、传统的登录流程
传统架构在集群环境中存在的问题:
在集群环境中。需要把同一套代码部署到多台服务器上,每个工程都有自己独立的session。
在集群环境中每个工程都有自己的session,如果把用户信息写入session而不共享的话,会出现用户反复登录的情况。
解决方案:
1.配置Tomcat集群。配置TomcatSession复制。节点数不要超过5个。
2.可以使用session服务器,保存session信息。使每个节点是无状态的,需要模拟session。
单点登录系统就是使用redis模拟session,实现session的统一管理。
单点登录流程图:
三。代码实现:
在resource.properties配置文件中加入
#redis\u4e2d\u7528\u6237Session\u7684\u524d\u7f00
USER_SESSION=USER_SESSION
#session\u7684\u8fc7\u671f\u65f6\u95f4
SESSION_EXPIRE=1800
service层:
@Value("${USER_SESSION}")
private String USER_SESSION;
@Value("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE;
public TaotaoResult 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 TaotaoResult.build(400, "用户名不存在");
}
TbUser user = list.get(0);
//校检密码 密码需要加密后才能比对
if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {
return TaotaoResult.build(400, "密码错误");
}
//2.登录成功后生成一个token
String token = UUID.randomUUID().toString();
//3.吧用户信息保存到redis中,保存之前先清空密码
user.setPassword(null);
jedisClient.set(USER_SESSION+":"+token, JsonUtils.objectToJson(user));
//设置token的过期时间
jedisClient.expire(USER_SESSION+":"+token, SESSION_EXPIRE);
return TaotaoResult.ok(token);
}
controller层
@RequestMapping(value="/user/login",method=RequestMethod.POST)
@ResponseBody
public TaotaoResult login(String username,String password,
HttpServletRequest request,HttpServletResponse response){
TaotaoResult result = userService.login(username, password);
String token = result.getData().toString();
//把token存入cookie
CookieUtils.setCookie(request, response, "TOKEN_KEY", token);
return result;
}
根据token查询用户信息
public TaotaoResult getUserByToken(String token) {
//根据token查询redis
String json = jedisClient.get(USER_SESSION+":"+token);
if (StringUtils.isBlank(json)) {
return TaotaoResult.build(400, "用户登录已经过期,请重新登录");
}
//json转换成user对象
TbUser user = JsonUtils.jsonToPojo(json, TbUser.class);
return TaotaoResult.ok(user);
}
欢迎识别下方二维码,关注小编微信公众号,可以获取跟多Java资料: