最近日常開發的項目在發布到測試環境時遇到登錄session不一致的問題,特此將排查過程記錄一下:
問題描述:
項目用到了登錄校驗,用戶登錄之后,將數據庫查詢出來的User對象放入Session中保存,當發其他需要校驗登錄的交易時,使用攔截器配合SpringAOP進行登錄校驗,校驗邏輯很簡單,就是將之前登錄放入Session的User對象取出判斷是否為空,如果不為空則繼續執行后面的邏輯代碼,為空則返回用戶未登錄,本地環境測試了一點問題沒有,但是上了環境之后,用戶登陸完成之后發別的交易總是返回用戶未登錄;
問題排查:
1、首先本地測試沒有問題,上環境之后有問題,唯一的區別是上了環境之后,環境上使用了nginx方向代理,並且通過瀏覽器發現存入Session的SessionID和取Session的SessionID不一致;
經過百度得出nginx方向代理需要設置下cookie復制。配置偽代碼如下:
location /aaaaa/bbbbbb { #代理跳轉的路徑 proxy_pass http://localhost:8080/bbbbbb; #proxy_cookie_path 后面的兩個斜杠表示將源訪問地址的“/”路徑的cookie復制到目標地址的“/”路徑。 proxy_cookie_path /bbbbbb /aaaaa/bbbbbb; }
2、改了之后發現問題並沒有解決,后面才發現一個大坑,因為我登錄之后直接將數據庫返回的User對象放入了Session,偽代碼如下:
//查詢數據庫,返回User對象 User u = userService.checkLogin(user); session.setAttribute(USER_IN_SESSION,u); //session過期時間設置,以秒為單位,即在沒有活動30分鍾后,session將失效 session.setMaxInactiveInterval(30 * 60);
可以看出,我這里直接將User對象放入Session中的,而不是往Session中存入JSON串什么的,並且我這個User對象並沒有序列化, z之后給對象implements Serializable 序列化之后,問題解決,真的是尷尬呀,后面還是建議大家在創建數據對象的時候都序列化一下~~~