学习内容
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
![](https://img-blog.csdnimg.cn/20190226173323308.png)