redis缓存+session 实现单点登录
一、单点登录介绍
单点登录(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("已登出");
}
}
三、不同域下的单点登录
待更新
redis缓存+session 实现单点登录的更多相关文章
- springcloud微服务基于redis集群的单点登录
springcloud微服务基于redis集群的单点登录 yls 2019-9-23 简介 本文介绍微服务架构中如何实现单点登录功能 创建三个服务: 操作redis集群的服务,用于多个服务之间共享数据 ...
- Django之使用redis缓存session,历史浏览记录,首页数据实现性能优化
Redis缓存session 配置Django缓存数据到redis中 # diango的缓存配置 CACHES = { "default": { "BACKEND&quo ...
- TP、PHP同域不同子级域名共享Session、单点登录
TP.PHP同域不同子级域名共享Session.单点登录 目的: 为了部署同个域名下不同子级域名共享会话,从而实现单点登录的问题,一处登录,同域处处子系统即可以实现自动登录. PHP支持通过设置coo ...
- Redis缓存Mysql模拟用户登录Java实现实例[www]
Redis缓存Mysql模拟用户登录Java实现实例 https://jingyan.baidu.com/article/09ea3ede1dd0f0c0aede3938.html redis+mys ...
- SpringBoot 整合Shiro实现动态权限加载更新+Session共享+单点登录
作者:Sans_ juejin.im/post/5d087d605188256de9779e64 一.说明 Shiro是一个安全框架,项目中主要用它做认证,授权,加密,以及用户的会话管理,虽然Shir ...
- 如何通过session控制单点登录
web服务器为每一个浏览器实例对应一个session.这个session有自己的一个独立id,这个id保存在浏览器的cookie中(这个cookie貌似随着这个浏览器实例的关闭而清除),访问web服务 ...
- Thinkphp3.2 Redis缓存session
Thinkphpsession缓存没有redis类库 Redis.class.php放在Library/Think/Session/Driver/下: <?php /** * +-------- ...
- session 控制单点登录
在我登录成功之后,我会 session.setAttribute("user", userMap);//设置session 所以就写了一个监听器来控制登录的. package or ...
- Redis缓存Mysql模拟用户登录Java实现实例
https://blog.csdn.net/suneclipse/article/details/50920396
随机推荐
- Map四种获取key和value值的方法,以及对map中的元素排序(转)
获取map的值主要有四种方法,这四种方法又分为两类,一类是调用map.keySet()方法来获取key和value的值,另一类则是通过map.entrySet()方法来取值,两者的区别在于,前者主要是 ...
- Mysql使用SSL连接
最近项目中用到了SSL连接,记录一下,环境为windows10,Mysql版本为5.6 查看是否支持 SSL 首先在 MySQL 上执行如下命令, 查询是否 MySQL 支持 SSL: mysql&g ...
- SpringBoot 2 快速整合 | Hibernate Validator 数据校验
概述 在开发RESTFull API 和普通的表单提交都需要对用户提交的数据进行校验,例如:用户姓名不能为空,年龄必须大于0 等等.这里我们主要说的是后台的校验,在 SpringBoot 中我们可以通 ...
- 在一个升序数组中添加最少的数字,使得从1--n之间所有的数都能用数组中几个数的和表示
一个Java的笔试题上面遇到的题,当时没有做出来. 拆分: 序列升序 1--n所有的数都要能表示 用数组中数字的和表示 添加最少的数字 思路:这个要先从小的数开始表示,因为大的数可以用小数表示. 1- ...
- Phpstudy被暴存在隐藏后门-检查方法
Phpstudy被暴存在隐藏后门-检查方法 一.事件背景 Phpstudy软件是国内的一款免费的PHP调试环境的程序集成包,通过集成Apache.PHP.MySQL.phpMyAdmin.ZendOp ...
- 详细的App推广前的准备工作
App开发完成后,推广App自然就成为下一步工作的重点.兵马未动,粮草先行,这里为大家整理了一份App推广前需要准备一些事项,希望能给正在准备开展App推广的小伙伴们一些帮助. 众所周知,App推广的 ...
- Docker学习之Dockerfile
通过编写简单的文件创建docker镜像 dockerfile 用来创建docker镜像. 格式 : FROM alpine:latest MAINTAINER XSW CMD echo "h ...
- 利用IntelliJ IDEA与Maven开发scala程序,并打包提交到spark集群
https://zhuanlan.zhihu.com/p/23141509 https://blog.csdn.net/u011470552/article/details/54564636 http ...
- js 混合排序(类似中文手机操作系统中的通讯录排序)
在阳光明媚最适合打盹的下午, 特意静音的手机竟然动起来了, 你没看错, 它震动了.... 上帝(顾客)来电, "报表查询系统左侧树状菜单中设备的中文名称不能排序", 要增加排序功能 ...
- MyEclipse 中无法直接使用BaseEncoder问题
首先 :点击项目---->build path--->configure Build Path 然后:java build path --->libraries--->JRE ...