php 获取cookieid,Redis实现Session共享详解
Redis實現Session共享
這幾天在做session共享這么一個小模塊,也查了好多資料,給我的感覺,就是太亂了,一直找不到我想要的東西,幾乎全部實現方法都與我的想法不一樣,在這里,我總結一下自己是如何用Redis實現session共享的,方便自己以后查詢,也希望能給有這方面需求的朋友一些幫助。相關專題推薦:php session (包含圖文、視頻、案例)
先說一下我的開發環境:nginx、redis、tomcat,用moven構建項目,jetty服務器運行,所以在這里,下面也會涉及一下如何用maven打war包,部署在tomcat上運行。
redis是一個key-value數據庫,存值取值,全靠這個key了,這里啰嗦一句,因為原創,專業的介紹我就不粘貼了,想了解的官方介紹的可以自行search.
pom.xml中配置:
redis.clients
jedis
2.8.1
org.springframework.data
spring-data-redis
1.7.2.RELEASE
aplicationContext-redis.xml中配置
配置完畢后,開始代碼實現:
在LoginController里:
第一步,引入RedisTemplate
@Autowired
@Qualifier("writeRedisTemplate")
private StringRedisTemplate writeTemplate;
這里只需要引入writeRedisTemplate即可,在登陸的時候,只負責寫,只有在再次刷新的時候,經過過濾器,才需要讀
第二步,正常登陸流程,登陸成功之后,request還要保存session信息
第三步,設置cookie值,把作為保存userSession信息在redis中的key值存入cookie,刷新瀏覽器的時候,過濾器可以從cookie中取到key值,進而去redis取對應的value值,即userSessionString domain = request.getServerName();
String cookieId=MD5Util.MD5Encode("uasLoginer", "UTF-8");
//生成token,用作session在redis存儲中的key值
StringredisSessionKey= UUID.randomUUID().toString();
Cookie uasLoginer = new Cookie(cookieId, redisSessionKey);
if (domain.startsWith("uas.")) {
uasLoginer.setDomain(domain.substring(4,domain.length()));
}else {
uasLoginer.setDomain(domain);
}
uasLoginer.setMaxAge(60000);
uasLoginer.setPath("/");
response.addCookie(uasLoginer);
這里cookie跨域setDomain和setPath設置
第四步,把userSession信息存入redis中
RedisTemplate中寫入redis的值要為String類型,需要把userSession對象轉成Json字符串userSessionString = JSON.toJSONString(userSession);
在轉Json的時候,遇到問題,導入import com.alibaba.fastjson.JSON;一直失敗,發現pom中沒有依賴Json的關系,如果有遇到相同的問題,可以檢查下在pom.xml中是否有關于json的依賴關系,沒的話,在pom.xml中導入json的依賴關系,如下:
net.sf.json-lib
json-lib
2.3
jdk15
寫入redis的代碼如下:writeTemplate.opsForHash().put(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey,redisSessionKey, userSessionString);
writeTemplate.expire(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey, 1800L, TimeUnit.SECONDS);//設置redis中值的有效期
完成這一操作,用戶的session信息已經存入到redis中,可在redis中查看是否存入。
第五步:進入頁面后,刷新頁面,請求會經過過濾器,在Filter.Java中讀取redis的值并進行一些處理
在過濾器這里,就無法通過注解的方式引入redisTemplate,可以通過如下的方式引入:
BeanFactory beans = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext());
StringRedisTemplate readTemplate = (StringRedisTemplate) beans.getBean("readRedisTemplate");
StringRedisTemplate writeTemplate = (StringRedisTemplate) beans.getBean("writeRedisTemplate");
過濾器從cookie中取出redis的key值,用readTemplate讀出value值String cookid=MD5Util.MD5Encode("uasLoginer", "UTF-8");
Cookie[] cookies = req.getCookies();
String redisSessionKey = "";
if(cookies != null){
for (Cookie cookie : cookies) {
if(cookie.getName().equals(cookid)){
redisSessionKey = cookie.getValue() ;
}
}
}
UserSession userSession = null;
String userSessionString = (String) readTemplate.boundHashOps(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey).get(redisSessionKey);
if(null != userSessionString ){
@SuppressWarnings("static-access")
JSONObject obj = new JSONObject().fromObject(userSessionString);//將json字符串轉換為json對象
userSession = (UserSession)JSONObject.toBean(obj,UserSession.class);
writeTemplate.expire(UasContants.REDIS_USER_SESSION_KEY+"_"+redisSessionKey, 1800L, TimeUnit.SECONDS);
request.getSession().setAttribute(UasContants.USER_SESSION, userSession);
}
if (userSession != null) {
chain.doFilter(req, res);
return;
}else {
res.sendRedirect(UasContants.LOGIN_URL);
return;
}
在這里,另外附上關于web.xml關于LoginFilter的配置,有需要的可以參考下:
org.springframework.web.context.ContextLoaderListener
loginFilter
com.sfbest.uas.filter.LoginFilter
excludePaths
/login,/user/login,/user/auth
loginFilter
/*
按照上面的配置,就可以用redis實現session共享的功能,但我在開發的時候,遇到一個蛋疼的問題,在測試環境上,
把項目部署在兩臺tomcat服務器上的時候,cookie里一直存不進去redis的key值,單臺可以存進去,經過長期的檢測,
終于發現是nginx配置出的問題,引以為戒,深深的陰影。下面我貼出我正常運行時nginx的配置代碼
upstream uassessiontest.d.com {
server 10.103.16.226:8088;
server 10.103.16.226:8089;
}
server {
log_format sf_uastest '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $http_cookie';
listen 80;
server_name uassessiontest.d.com;
access_log /var/log/nginx/uassessiontest.log sf_uastest;
location / {
rewrite ^/$ /uas/ break;
proxy_pass http://uassessiontest.d.com;
}
}
紅色的為當初少配的部分,這些部分是的作用是往瀏覽器端寫入cookie值。
總結
以上是生活随笔為你收集整理的php 获取cookieid,Redis实现Session共享详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql 错误问题_Mysql常见的几
- 下一篇: php日期转时间戳,指定日期转换成时间戳