分布式系列 单点登录和session共享实现
来源:互联网 发布:常见web前后端数据交互 编辑:程序博客网 时间:2024/05/16 09:08
上篇文章简单的描述了下单点登录的场景和解决单点登录问题的几套方案。
本文将从具体实现层面剖析如何实现SSO和session共享。
假设我们有三个子系统:Project1;Project2,Project 3,此时,访问每个子系统都会有自己的会话。只要他们之间互认了sessionID,我们就能任意在个子系统之间穿梭访问。
这是SSO的一张流程图。比较详细的上描述了用户从登陆页面到访问用户中心、订单系统的过程,采用了redis保存会话的共享机制,也是当前比较常用的一套实现方案。
该方案具有明显的好处:redis存取速度快,不会网出现多个节点session复制的问题,且效率高。
查询数据校验:
@Servicepublic class UserRegisterServiceImpl implements UserRegisterService {@Autowiredprivate TbUserMapper userMapper;@Overridepublic SystemResult checkInfo(String value, String type) throws Exception {boolean result = false;//type为类型,可选参数1、2、3分别代表username、phone、emailif ("1".equals(type)) {result = checkUserName(value);} else if ("2".equals(type)) {result = checkPhone(value);} else if ("3".equals(type)) {result = checkEmail(value);}//返回结果if (result) {return TaotaoResult.ok(result);}throw new DataException("此数值已经存在");}private boolean checkUserName(String userName) throws Exception {//创建查询条件TbUserExample example = new TbUserExample();Criteria criteria = example.createCriteria();criteria.andUsernameEqualTo(userName);List<TbUser> list = userMapper.selectByExample(example);//判断结果中是否存在if (list == null || list.isEmpty()) {return true;}return false;}private boolean checkPhone(String phone) throws Exception {//创建查询条件TbUserExample example = new TbUserExample();Criteria criteria = example.createCriteria();criteria.andPhoneEqualTo(phone);List<TbUser> list = userMapper.selectByExample(example);//判断结果中是否存在if (list == null || list.isEmpty()) {return true;}return false;}private boolean checkEmail(String email) throws Exception {//创建查询条件TbUserExample example = new TbUserExample();Criteria criteria = example.createCriteria();criteria.andEmailEqualTo(email);List<TbUser> list = userMapper.selectByExample(example);//判断结果中是否存在if (list == null || list.isEmpty()) {return true;}return false;}}
用户注册实现:
@Overridepublic SystemResult register(TbUser user) throws Exception {//有效性验证if (StringUtils.isBlank(user.getUsername())) {throw new DataException("用户名不能为空");}if (StringUtils.isBlank(user.getPassword())) {throw new DataException("密码不能为空");}if (StringUtils.isBlank(user.getPhone())) {throw new DataException("手机不能为空");}//转换md5user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));//完善user信息user.setCreated(new Date());user.setUpdated(new Date());//添加到数据库userMapper.insert(user);return SystemResult.ok();}
@Servicepublic class UserLoginServiceImpl implements UserLoginService {@Autowiredprivate TbUserMapper userMapper;@Autowiredprivate JedisCluster jedisCluster;@Value("${USER_TOKEN_KEY}")private String USER_TOKEN_KEY;@Value("${SESSION_EXPIRE_TIME}")private Integer SESSION_EXPIRE_TIME;@Overridepublic SystemResult login(String username, String password) throws Exception {//根据用户名查询用户信息TbUserExample example = new TbUserExample();Criteria criteria = example.createCriteria();criteria.andUsernameEqualTo(username);List<TbUser> list = userMapper.selectByExample(example);if (null == list || list.isEmpty()) {throw new DataException("用户不存在");}//核对密码TbUser user = list.get(0);if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())) {throw new DataException("密码错误");}//登录成功,把用户信息写入redis//生成一个用户tokenString token = UUID.randomUUID().toString();jedisCluster.set(USER_TOKEN_KEY + ":" + token, JsonUtils.objectToJson(user));//设置session过期时间jedisCluster.expire(USER_TOKEN_KEY + ":" + token, SESSION_EXPIRE_TIME);return SystemResult.ok(token);}}
用户查询:
@Servicepublic class UserTokenServiceImpl implements UserTokenService {@Autowiredprivate JedisCluster jedisCluster;@Value("${USER_TOKEN_KEY}")private String USER_TOKEN_KEY;@Value("${SESSION_EXPIRE_TIME}")private Integer SESSION_EXPIRE_TIME;/** * 根据token取用户信息 */@Overridepublic SystemResult getUserByToken(String token) throws Exception {//从redis中取用户信息String userJson = jedisCluster.get(USER_TOKEN_KEY + ":" + token);if (StringUtils.isBlank(userJson)) {throw new DataException("该用户已过期");}//把json转换成user对象TbUser user = JsonUtils.jsonToPojo(userJson, TbUser.class);//更新用户有效期jedisCluster.expire(USER_TOKEN_KEY + ":" + token, SESSION_EXPIRE_TIME);return SystemResult.ok(user);}}
后续登录拦截器的配置,就不在此多说了。
阅读全文
0 0
- 分布式系列 单点登录和session共享实现
- 分布式系列 单点登录和session共享
- redis实现session共享,实现单点登录
- 单点登录实现(spring session+redis完成session共享)
- 单点登录实现(spring session+redis完成session共享)
- 单点登录实现(spring session+redis完成session共享)
- 单点登录实现(spring session+redis完成session共享
- 基于Cookie和session,实现单点登录
- session共享和单点登录 springboot的实践和思考
- 使用memcache实现单点登录(session共享)
- tomcat使用redis共享session并实现单点登录
- 使用Memcache实现Session共享(单点登录)的原理
- 单点登录 Tomcat7集群共享Session 基于redis实现统一管理
- 同一tomcat下实现多应用session共享 单点登录
- 单点登录SSO-使用session共享方式
- SPRING SESSION实现单点登录
- jsonp+session实现单点登录
- spring session和Redis数据库实现单点登录功能
- Maven异常: No compiler is provided in this environment. Perhaps you are running on a JRE rather than a
- English summary in June
- 菜鸟超神之路:按位与|,按位或&,详解分析
- 栈空间和堆空间
- 机器学习算法之线性回归(Linear Regression)
- 分布式系列 单点登录和session共享实现
- Rundll32.exe参数传递问题解决方法
- 简单MD5加密类
- java多线程:ExecutorService解析(五)
- BZOJ1050(HAOI2006)[旅行comf]--并查集
- Frank的【python网络爬虫系列教程】~序章&目录
- JAVA数据流概念及标准数据流的实现
- 暑假来临!花了点时间用flash3d做了一个MV歌曲!
- httpResult