SSO(Single Sign On)单点登录 使用cookie、redis做两个案例

学习内容

SSO:一次登录,处处穿梭 同域

SSO:不同的应用位于同一个域名下面 跨域

SSO:不同的应用位于不同的域名下面

使用技术:springboot+redis

 

主要流程

实现工具类存放和校验的方法,例如同域使用cookie

/**
 * 登录校验工具类
 *
 * @author changqing
 * @date 2019-02-26
 */
public class LoginCheck {
    /**
     * 测试用户名
     */
    public static final String USERNAME = "user";
    /**
     * 测试密码
     */
    public static final String PASSWORD = "123";
    /**
     * Cookie键
     */
    public static final String COOKIE_NAME = "ssocookie";
    /**
     * Cookie值
     */
    public static final String COOKIE_VALUE = "sso";

    /**
     * 登录用户名和密码校验
     *
     * @param username 用户名
     * @param password 密码
     * @return true用户名和密码正确;false用户名或密码错误
     */
    public static boolean checkLogin(String username, String password) {
        return USERNAME.equalsIgnoreCase(username) && PASSWORD.equalsIgnoreCase(password);
    }

    /**
     * 校验Cookie
     *
     * @param request
     * @return true正确;false错误
     */
    public static boolean checkCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            return false;
        }
        for (Cookie cookie : cookies) {
            if (COOKIE_NAME.equals(cookie.getName()) &&
                    COOKIE_VALUE.equals(cookie.getValue())) {
                return true;
            }
        }
        return false;
    }
}
@GetMapping("/login")
public Map<String, Object> doLogin(String username, String password, HttpServletResponse response) {
    Map<String, Object> result = new HashMap<>();
    // 校验用户名和密码
    boolean ok = LoginCheck.checkLogin(username, password);
    // 判断是否登录成功
    if (ok) {
        // 添加Cookie
        response.addCookie(new Cookie(LoginCheck.COOKIE_NAME, LoginCheck.COOKIE_VALUE));
        result.put(LoginCheck.COOKIE_NAME, LoginCheck.COOKIE_VALUE);
    }
    //登录存储成功状态,可根据自己需求返回响应信息
    return result;
}
@GetMapping("/hello")
public String hello1(HttpServletRequest request) {
    //访问接口校验是否已经登录过
    return "登录:" + LoginCheck.checkCookie(request);
}

只要登录成功一次然后在写任何接口加入校验判断都是登录成功了。

cookie借鉴:https://segmentfault.com/a/1190000008933546#articleHeader5

 

 

实现redis工具类存放和校验的方法不同域名使用:

工具类我自己简单的封装了一下redis 可根据自己的需求使用不需要的直接删了

/**
 * 缓存工具类
 * @author changqing 
 */
@Component
public class CacheUtil {

    @Autowired
    private StringRedisTemplate cache;
    private final String KEY = "USER";
    private final String PHONECODE = "PHONECODE";
    public final static String USERTYPE = "USERTYPE";

    /**
     * 设置缓存
     *
     * @param key
     * @param value
     */
    public void setCache(@Valid @NotNull @Length(min = 1) String key, @NotNull @Length(min = 1) String value) {
        cache.opsForValue().set(key, value);
    }

    /**
     * 设置缓存+时效
     *
     * @param key
     * @param value
     * @param minute
     */
    public void setCache(@Valid @NotNull @Length(min = 1) String key, @NotNull @Length(min = 1) String value, @Min(1) int minute) {
        cache.opsForValue().set(key, value, minute, TimeUnit.MINUTES);
    }

    /**
     * 验证
     *
     * @param key
     * @param value
     * @return
     */
    public boolean getCache(@Valid @NotNull @Length(min = 1) String key, String value) {
        String s = cache.opsForValue().get(key);
        if (s == null) {
            return false;
        }
        return s.equals(value);
    }

    /**
     * 获取
     *
     * @param key
     * @return
     */
    public String getCache(@Valid @NotNull @Length(min = 1) String key) {
        String s = cache.opsForValue().get(key);
        return s;
    }

    /**
     * 存入登录cache
     *
     * @param uid 用户id
     * @return
     */
    public String setLoginCache(long uid) {
        String sid = UUID.randomUUID().toString();
        //30分钟失效(以秒为单位)
        cache.opsForValue().set(KEY + uid, sid, 60, TimeUnit.MINUTES);
        return sid;
    }

    /**
     * 获取登录cache
     *
     * @param uid 用户id
     * @param sid 验证标志
     * @return
     */
    public boolean getLoginCache(long uid, String sid) {
        String s = cache.opsForValue().get(KEY + uid);
        if (s == null) {
            return false;
        }
        return s.equals(sid);
    }

    /**
     * 存入手机验证码
     *
     * @param phone
     * @param code
     */
    public void setPhoneCode(String phone, int code) {
        cache.opsForValue().set(PHONECODE + phone, code + "", 5, TimeUnit.MINUTES);
    }

    /**
     * 获取手机验证码
     *
     * @param phone
     * @param code
     * @return
     */
    public boolean getPhoneCode(String phone, int code) {
        String s = cache.opsForValue().get(PHONECODE + phone);
        if (s == null) {
            return false;
        }
        return s.equals(code + "");
    }
}
/**
 * 用户controller
 * @author changqing
 */
public class UserController{
    @Autowired
    private CacheUtil cacheUtil;
    @GetMapping("/login")
    public Map<String, Object> login(String username, String password) {
        Map<String, Object> result = new HashMap<>();
        //校验用户名和密码 判断是否登录成功
        if (username.equalsIgnoreCase("user") && password.equalsIgnoreCase("666")) {
            //拿到用户的id 数据库肯定有的吧 只要是用户的唯一标志就行 这里我先随便写一个
            long uid=668899;
            //之后这个存入方法就会为这个用户生成一个唯一标志返回给前端 
            //key是用户类型+id value我叫它sid
            result.put(cacheUtil.KEY+uid,cacheUtil.setLoginCache(uid));
        }
        //登录存储成功状态,可根据自己需求返回响应信息
        return result;
    }
    
    @GetMapping(value = "getByUserId")
    public String getByUserId(Long ckuid,String cksid) {
        //获取前端携带的参数sid判断一下 不懂的话看上面的方法
        if (!cacheUtil.getLoginCache(ckuid,cksid)) {
            return "登陆失效";
        }
        return "查看成功";
    }
}

完事了 个人觉得用redis比较好 。。。。。。 有什么建议或者补充的可联系QQ:501499471 欢迎提意见相互学习 哈哈哈 end

 

cheer

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值