第十天:SSO

SSO

- 单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统

  • SSO单点登录
    • 实现:redis+token
    1. 登录时生成token写入redis
    2. 检查token
    • 实现代码
      在这里插入图片描述
      • resource.properties
        # 用户session信息在redis中保存的key
        REDIS_USER_SESSION_KEY=REDIS_USER_SESSION
        # session的过期时间30分钟
        SSO_SESSION_EXPIRE=1800
        
      • JedisClientSingle.java
        public class JedisClientSingle implements JedisClient {
        
            @Autowired
            private JedisPool jedisPool;
        
            @Override
            public String get(String key) {
                Jedis jedis = jedisPool.getResource();
                String string = jedis.get(key);
                jedis.close();
                return string;
            }
        
            @Override
            public String set(String key, String value) {
               Jedis jedis = jedisPool.getResource();
               String string = jedis.set(key, value);
               jedis.close();
                return string;
            }
        
            @Override
            public String hget(String hkey, String key) {
                Jedis jedis = jedisPool.getResource();
                String string = jedis.hget(hkey, key);
                jedis.close();
                return string;
            }
        
            @Override
            public long hset(String hkey, String key, String value) {
                Jedis jedis = jedisPool.getResource();
                Long result = jedis.hset(hkey, key, value);
                jedis.close();
                return result;
            }
        
            @Override
            public long incr(String key) {
                Jedis jedis = jedisPool.getResource();
                Long result = jedis.incr(key);
                jedis.close();
                return result;
            }
        
            @Override
            public long expire(String key, int second) {
                Jedis jedis = jedisPool.getResource();
                Long result = jedis.expire(key, second);
                jedis.close();
                return result;
        
            }
        
            @Override
            public long ttl(String key) {
                Jedis jedis = jedisPool.getResource();
                Long result = jedis.ttl(key);
                jedis.close();
                return result;
        
            }
        
            @Override
            public long del(String key) {
                Jedis jedis = jedisPool.getResource();
                Long result = jedis.del(key);
                jedis.close();
                return result;
            }
        
            @Override
            public long hdel(String hkey, String key) {
                Jedis jedis = jedisPool.getResource();
                Long result = jedis.hdel(hkey, key);
                jedis.close();
                return result;
            }
        }
        
      • Service
        @Service
        public class UserServiceImpl implements UserService {
        
            @Autowired
            private TbUserMapper userMapper;
        
            @Autowired
            private JedisClient jedisClient;
        
            @Value("${REDIS_USER_SESSION_KEY}")
            private String REDIS_USER_SESSION_KEY;
        
            @Value("${SSO_SESSION_EXPIRE}")
            private Integer SSO_SESSION_EXPIRE;
        
            /** 
            * @Description: 用户登录
            * @Param: [username, password] 
            * @return: com.taotao.common.pojo.TaotaoResult 
            * @Author: 尘
            * @Date: 2019/2/16 
            */
            @Override
            public TaotaoResult userLogin(String username, String password) {
        
                TbUserExample example = new TbUserExample();
                TbUserExample.Criteria criteria = example.createCriteria();
                criteria.andUsernameEqualTo(username);
                List<TbUser> list = userMapper.selectByExample(example);
                // 如果没有此用户名
                if(null == list || list.size() == 0){
                    return TaotaoResult.build(400, "用户名密码错误");
                }
                TbUser user = list.get(0);
                // 比对密码
                if(!DigestUtils.md5DigestAsHex(password.getBytes()).equals(user.getPassword())){
                    return TaotaoResult.build(400,"用户名或密码错误");
                }
                // 生成 token
                String token = UUID.randomUUID().toString();
                // 保存用户之前,把用户对象中的密码清空
                user.setPassword(null);
                // 把用户信息写入redis
                jedisClient.set(REDIS_USER_SESSION_KEY + ":" + token, JsonUtils.objectToJson(user));
                // 设置session过期时间
                jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
                // 返回token
                return TaotaoResult.ok(token);
                
            }
        
            /** 
            * @Description: 接收并检查token
            * @Param: [token] 
            * @return: com.taotao.common.pojo.TaotaoResult 
            * @Author: 尘
            * @Date: 2019/2/16 
            */
            @Override
            public TaotaoResult getUserByToken(String token) {
                // 根据 token 从 redis 中查询用户信息
                String json = jedisClient.get(REDIS_USER_SESSION_KEY + ":" + token);
                // 判断是否为空
                if(StringUtils.isBlank(json)){
                    return TaotaoResult.build(400, "session已经过期,请重新登录");
                }
                // 更新过期时间
                jedisClient.expire(REDIS_USER_SESSION_KEY + ":" + token, SSO_SESSION_EXPIRE);
                // 返回用户信息
                return TaotaoResult.ok(JsonUtils.jsonToPojo(json, TbUser.class));
            }
        }
        
      • Controller
        @Controller
        @RequestMapping("/user")
        public class UserController {
        
            @Autowired
            private UserService userService;
        
            /** 
            * @Description: 用户登录
            * @Param: [username, password] 
            * @return: com.taotao.common.pojo.TaotaoResult 
            * @Author: 尘
            * @Date: 2019/2/16 
            */
            @RequestMapping(value = "/login", method = RequestMethod.POST)
            @ResponseBody
            public TaotaoResult userLogin(String username, String password){
                try {
                    TaotaoResult result = userService.userLogin(username, password);
                    return result;
                }catch (Exception e){
                    e.printStackTrace();
                    return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
                }
            }
        
            /** 
            * @Description: token检查 
            * @Param: [token, callback] 
            * @return: java.lang.Object 
            * @Author: 尘
            * @Date: 2019/2/16 
            */
            @RequestMapping("/token/{token}")
            @ResponseBody
            public Object getUserByToken(@PathVariable String token, String callback) {
                TaotaoResult result = null;
                try {
                    result = userService.getUserByToken(token);
                } catch (Exception e) {
                    e.printStackTrace();
                    result = TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
                }
        
                //判断是否为jsonp调用
                if (StringUtils.isBlank(callback)) {
                    return result;
                } else {
                    MappingJacksonValue mappingJacksonValue = new MappingJacksonValue(result);
                    mappingJacksonValue.setJsonpFunction(callback);
                    return mappingJacksonValue;
                }
        
            }
        
        }
        
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章