完整的redis保存用户信息,cookie保存sessionId实现登录流程
程序员文章站
2024-03-19 22:27:34
...
1. 完整的redis保存用户信息,cookie保存sessionId实现登录流程
登录流程
- cookid中存入sessionId并持久化到本地,把它的过期时间设置长一点
//1. 把登录信息存入cookie 中
CookieUtil.writeLoginToken(httpServletResponse,session.getId());
-----------------》writeLoginToken()方法
/**
* 存入cookie到本地
*/
public static void writeLoginToken(HttpServletResponse response,String token){
Cookie ck = new Cookie(COOKIE_NAME,token);
//跨域共享,设置的值是B机器的域名,所以当B机器访问这个Cookie的时候是能访问到的
ck.setDomain(COOKIE_DOMAIN);
//代表设置在根目录
ck.setPath("/");
ck.setHttpOnly(true);
//单位是秒。如果这个maxAge不设置的话,cookie就不会写入硬盘,而是写在内存。只在当前页面有效。
//如果是-1,代表永久
ck.setMaxAge(60 * 60 * 24 * 365);
log.info("write cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
response.addCookie(ck);
}
- redis中存入用户信息(value),存入之前把用户信息转换成json格式,把sessionId作为key,并设置过期时间
//2. 把登录信息存入redis 中(response.getData()获得了查询出来的user对象)
RedisShardedPoolUtil.setEx(session.getId(), JsonUtil.obj2String(response.getData()),Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
-----------------》setEx()法
/**
* 存入一个值并设置过期时间
*/
//exTime的单位是秒
public static String setEx(String key,String value,int exTime){
ShardedJedis jedis = null;
String result = null;
try {
jedis = RedisShardedPool.getJedis();
result = jedis.setex(key,exTime,value);
} catch (Exception e) {
log.error("setex key:{} value:{} error",key,value,e);
RedisShardedPool.returnBrokenResource(jedis);
return result;
}
RedisShardedPool.returnResource(jedis);
return result;
}
访问流程
- 添加一个过滤器,每次访问.do结尾的方法,都会经过过滤器并重置redis中存储用户信息的时间
--------------》过滤器主要方法
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest)servletRequest;
//1. 从cookie中获取value值(也就是session的值)
String loginToken = CookieUtil.readLoginToken(httpServletRequest);
-----------》readLoginToken方法
/**
* 获取存储的cookie
*/
public static String readLoginToken(HttpServletRequest request){
Cookie[] cks = request.getCookies();
if(cks != null){
for(Cookie ck : cks){
log.info("read cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
log.info("return cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
return ck.getValue();
}
}
}
return null;
}
//2. 如果value不为空
if(StringUtils.isNotEmpty(loginToken)){
//2.1 通过session(也就是cookie的value和redis中的key)值获取用户信息
String userJsonStr = RedisShardedPoolUtil.get(loginToken);
--------------》get方法
/**
* 通过key获取一个值
*/
public static String get(String key){
ShardedJedis jedis = null;
String result = null;
try {
jedis = RedisShardedPool.getJedis();
result = jedis.get(key);
} catch (Exception e) {
log.error("get key:{} error",key,e);
RedisShardedPool.returnBrokenResource(jedis);
return result;
}
RedisShardedPool.returnResource(jedis);
return result;
}
User user = JsonUtil.string2Obj(userJsonStr,User.class);
--------------------》string2Obj方法
/**
*将json格式转换成匹配的对象或者集合;(1)
*
* @param str 要转换的json字符串
* @param clazz 要转换成的类型
*/
public static <T> T string2Obj(String str,Class<T> clazz){
if(StringUtils.isEmpty(str) || clazz == null){
return null;
}
try {
return clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
} catch (Exception e) {
log.warn("Parse String to Object error",e);
return null;
}
}
//2.2如果成功获取值,重新设置一个redis中的过期时间(因为每次拿到的用户信息就是从reids中拿的)
if(user != null){
//如果user不为空,则重置session的时间,即调用expire命令
RedisShardedPoolUtil.expire(loginToken, Const.RedisCacheExtime.REDIS_SESSION_EXTIME);
--------------------------------》expire方法
/**
* 设置key的有效期,单位是秒
*/
public static Long expire(String key,int exTime){
ShardedJedis jedis = null;
Long result = null;
try {
jedis = RedisShardedPool.getJedis();
result = jedis.expire(key,exTime);
} catch (Exception e) {
log.error("expire key:{} error",key,e);
RedisShardedPool.returnBrokenResource(jedis);
return result;
}
RedisShardedPool.returnResource(jedis);
return result;
}
}
}
//3. 放行
filterChain.doFilter(servletRequest,servletResponse);
}
- (访问了方法)获取redis中存入的登录信息
//1. 获取redis中存入的登录信息
String userJsonStr = RedisShardedPoolUtil.get(loginToken);
-------------------》get方法上面有
- 并转化成对象格式
//2. 转换成user对象格式
User user = JsonUtil.string2Obj(userJsonStr,User.class);
------------》string2Obj方法上面也有,注意这里只是一个类型转换
退出流程
- 删除cookie
//1. 删除cookie
CookieUtil.delLoginToken(httpServletRequest,httpServletResponse);
--------------》delLoginToken方法
/**
* 删除本地cookie
*/
public static void delLoginToken(HttpServletRequest request,HttpServletResponse response){
Cookie[] cks = request.getCookies();
if(cks != null){
for(Cookie ck : cks){
if(StringUtils.equals(ck.getName(),COOKIE_NAME)){
ck.setDomain(COOKIE_DOMAIN);
ck.setPath("/");
ck.setMaxAge(0);//设置成0,代表删除此cookie。
log.info("del cookieName:{},cookieValue:{}",ck.getName(),ck.getValue());
response.addCookie(ck);
return;
}
}
}
}
- 删除redis
//2. 删除redis
RedisShardedPoolUtil.del(loginToken);
----------------》del方法
/**
* 删除一个值
*/
public static Long del(String key){
ShardedJedis jedis = null;
Long result = null;
try {
jedis = RedisShardedPool.getJedis();
result = jedis.del(key);
} catch (Exception e) {
log.error("del key:{} error",key,e);
RedisShardedPool.returnBrokenResource(jedis);
return result;
}
RedisShardedPool.returnResource(jedis);
return result;
}
注意
:
- 例如登录流程之类的,他们是同一个方法中的两个步骤,只截取了主要部分,下面特意把它们使用的方法都写出来了,都是自己写好的工具类
- 注意设置的setDomain属性,因为nginx有两台tomcat,所以要实现单点登录,所以我们就要保证域名是一级域名,a和b两台服务器都能访问到的那种,这样两个tomcat才可以访问同一个cookie
上一篇: Swift系列之——UISearchBar的简单使用
下一篇: 第五节 Spring MVC
推荐阅读
-
Servlet通过Cookie保存用户信息,实现自动登录的demo.
-
完整的redis保存用户信息,cookie保存sessionId实现登录流程
-
asp.net利用cookie保存用户密码实现自动登录的方法
-
asp.net利用cookie保存用户密码实现自动登录的方法
-
php中使用cookie来保存用户登录信息的实现代码_PHP教程
-
php中使用cookie来保存用户登录信息的实现代码_PHP教程
-
php同时使用session和cookie来保存用户登录信息的实现代码,sessioncookie_PHP教程
-
php同时使用session和cookie来保存用户登录信息的实现代码
-
Django利用cookie保存用户登录信息的简单实现方法
-
php中使用cookie来保存用户登录信息的实现代码_php实例