第十天: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;
                }
        
            }
        
        }
        
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章