一、单点登录介绍

  单点登录(Single Sign On),简称为 SSO,是目前比较流行的企业业务整合的解决方案之一。SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

  同域下:单点登录是巧用了Cookie顶域的特性。

  不同域下:如果是不同域呢?不同域之间Cookie是不共享的,怎么办? 这个是使用CAS流程,单点登录的标准流程。

  相关详情:https://yq.aliyun.com/articles/636281 

        https://blog.csdn.net/qq_34246546/article/details/79493208

二、同域下的单点登录:利用sessionID+cookie+redis

 注意:因为我们是通过cookie的顶域特性,所以需要通过域名访问才能生成指定的cookie名称mmall_login_token 的cookie

自定义域名相关集群和负载均衡:https://www.cnblogs.com/FondWang/p/11677319.html

1. cookie工具类

package com.mmall.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* cookie工具类
*/
@Slf4j
public class CookieUtil {
private static final String COOKIE_DOMAIN = "wangjun.com"; //顶级域名
private static final String COOKIE_NAME = "mmall_login_token";//cookieName /**
* 从请求中读取cookie
* @param request
* @return
*/
public static String readLoginToken(HttpServletRequest request){
Cookie[] cks = request.getCookies();
if (cks != null){
for (Cookie cookie : cks){
log.info("read cookieName:{}, cookieValue:{}",cookie.getName(),cookie.getValue());
if (StringUtils.equals(cookie.getName(),COOKIE_NAME)){
log.info("return cookieName:{}, cookieValue:{}",cookie.getName(),cookie.getValue());
return cookie.getValue();
}
}
}
return null;
} /**
* 写入cookie
* @param response
* @param token
*/
public static void writeLoginToken(HttpServletResponse response, String token){
Cookie cookie = new Cookie(COOKIE_NAME, token);
cookie.setDomain(COOKIE_DOMAIN);
cookie.setPath("/"); //代表根目录,根目录以下的代码和页面可以获取到cookie //单位秒,如果不设置maxage,cookie就不会写入硬盘,而是写入内存,只在当前页面有效
cookie.setMaxAge(60 * 60 * 24 * 365);
log.info("write cookieName:{}, cookieValue:{}", cookie.getName(),cookie.getValue());
response.addCookie(cookie);
} /**
* 删除cookie
* @param request
* @param response
*/
public static void delLoginToken(HttpServletRequest request, HttpServletResponse response){
Cookie[] cks = request.getCookies();
if (cks != null){
for (Cookie cookie : cks){
if (StringUtils.equals(cookie.getName(),COOKIE_NAME)){
cookie.setDomain(COOKIE_DOMAIN);
cookie.setPath("/");
cookie.setHttpOnly(true); //无法用脚本访问cookie。当然不能全面防止,但可以提高安全性
cookie.setMaxAge(0);//设置为0,代表删除此cookie
log.info("del cookieName:{}, cookieValue:{}", cookie.getName(),cookie.getValue());
response.addCookie(cookie);
return;
}
}
} }
}

2. redis相关内容

  (1)使用集群:https://www.cnblogs.com/FondWang/p/11690791.html

  (2)单机redis:https://www.cnblogs.com/FondWang/p/11681222.html

3. json对象转换

  作用:将登录信息转换陈json,存储到redis中。

  https://www.cnblogs.com/FondWang/p/11703197.html

4. 登录代码

@Controller
@RequestMapping("/user/")
public class UserController { @Autowired
private IUserService iUserService;
/**
* 用户登录
* @param username
* @param password
* @param session
* @return
*/
@RequestMapping(value = "login.do",method = RequestMethod.POST)
@ResponseBody
public ServiceResponse<User> login(String username, String password, HttpSession session, HttpServletResponse httpServletResponse){
ServiceResponse<User> response = iUserService.login(username, password);
if (response.isSuccess()){
CookieUtil.writeLoginToken(httpServletResponse,session.getId()); //将内容写入cookie中
RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()), Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
}
return response;
} /**
* 登出 删除session
* @param httpServletRequest
* @return
*/
@RequestMapping(value = "logout.do",method = RequestMethod.POST)
@ResponseBody
public ServiceResponse<String> logout(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
String loginToken = CookieUtil.readLoginToken(httpServletRequest); //获取cookie的sessionID,如果存在,删除登出
CookieUtil.delLoginToken(httpServletRequest,httpServletResponse); //删除cookie中对应的token用户信息
RedisShardedPoolUtil.del(loginToken); //删除对应redis的用户信息
return ServiceResponse.createBySuccess("已登出");
}
}

三、不同域下的单点登录

  待更新

最新文章

  1. Symmetric Multiprocessor Organization
  2. Java split()用法
  3. Codeforces Gym 100114 J. Computer Network
  4. 深入掌握Java中的enum
  5. svn报错 400 Bad Request
  6. Nginx与Redis解决高并发问题
  7. android开发获取屏幕高度和宽度
  8. latch和DFF的区别和联系
  9. sharepoint 删除list里的所有内容
  10. 【四】注入框架RoboGuice使用:(Your First System Service Injection)
  11. 如何使用jedis进行发布订阅
  12. 基于微服务API级权限的技术架构
  13. 玩玩LED点阵屏(arduino nano)
  14. azkaban使用--传入动态参数
  15. promise之我见
  16. 【转】Leveldb源码分析——1
  17. iOS NSCache缓存类的了解
  18. Dictionary字典
  19. 深入理解softmax函数
  20. 使用mysqldump备份时为什么要加上 -q 参数(5.7默认为on)

热门文章

  1. SQL查询出距当前时间最近的一条或多条记录。
  2. Python—字符串和常用数据结构
  3. Spring Boot 入门之单元测试篇(五)
  4. librosa语音信号处理
  5. Spring——依赖注入(DI)详解
  6. Hadoop 之 HDFS的使用
  7. SpringBoot起飞系列-配置文件(三)
  8. FP-Tree算法详细过程(Java实现)
  9. Spring MVC-从零开始-分拆applicationContext. xrnl
  10. Java Map知识点