2013-01-09 181 views
1

我正在編寫使用Sprint Security進行身份驗證的Grails應用程序。我需要向用戶顯示一條消息,該用戶由於不活動而被自動註銷。Grails:處理HTTP會話超時事件

我的應用程序同時使用AJAX請求和直接請求到控制器。我注意到,對於AJAX請求衝刺安全返回代碼爲401的HTTP響應,我已經重新定義了默認的URL映射以這樣的方式:

class UrlMappings { 
    static mappings = { 
     // ... 

     "401" (controller: 'errors', action: 'inactivityLogout') 
    } 
} 

這裏是inacticityLogout()方法的主體:

def inactivityLogout() { 
    log.debug("the user is logged out due to inactivity") 
    session.setAttribute('inactivityMessage', "You have been logged out due to inactivity.") 
    render(status: 401) 
} 

然後LoginController檢查是否設置了inactivityMessage屬性,並在登錄頁面上顯示相應的消息。

問題是這個解決方案對於AJAX調用工作正常,但當我試圖通過單擊應用程序中的直接鏈接導航到另一個頁面時不起作用。在第二種情況下,日誌爲空,因此方法inactivityLogout未被調用。

Firebug顯示應用程序返回代碼302暫時移動,所以我雖然這是一個原因。但後來我注意到AJAX調用也返回了相同的代碼。所以,現在我不知道AJAX和非AJAX請求之間的區別以及爲什麼最後一個不是由Grails URL映射引擎處理。

任何想法,我目前的解決方案可能會出現什麼問題?這個問題能否以完全不同的方式解決?

謝謝!

+0

你想顯示消息的基礎上,他們點擊或自動會話過期時,根本沒有任何用戶交互? – Gregg

+0

是的,這個想法是在沒有任何用戶交互的情況下顯示消息。只是想讓用戶知道他爲什麼退出系統。 –

回答

2

使用jQuery,這是我做的:

$.ajaxSetup({ 
    statusCode: { 
    401: function() { 
     $('#ajaxAuthModal').modal('show'); 
    } 
    } 
}); 

我有一個在全球JS文件,這樣我所有的Ajax請求處理401然後,我只是顯示一個模式,告訴他們需要的用戶再次登錄。唯一需要實現的就是通過ajax輪詢安全資源。這將允許401函數在401返回時觸發。

像jQuery這樣的大多數JavaScript庫都應該有類似於$.ajaxSetup()的特性。

+0

謝謝,這是AJAX請求的絕佳解決方案!但是我還需要將用戶重定向到LoginController,當他嘗試導航到另一個時,並在那裏顯示消息。當會話過期時,Spring Security會自動將用戶重定向到LoginController,但是我需要了解用戶是否通過直接鏈接到網站來訪問此頁面,或者因爲處於非活動狀態而被註銷。可能是我沒有說清楚,但消息應該顯示爲不彈出,而是像登錄頁面上的純文本。 –

1

是的,這個想法是顯示沒有任何用戶交互的消息。只是想讓用戶知道他爲什麼退出系統。

因此,基本上一旦用戶加載頁面,就沒有與服務器的聯繫。服務器不能將消息「推送」到瀏覽器。所以你將不得不做的是檢查是否有JavaScript的活動會話。你可以很容易地使用計時器來做到這一點。

在你的main.gsp中設置一個javascript變量爲${session.maxInactiveInterval}。這會給你用戶會話的最大長度。只需開始一個setTimeout(function() { /* code to display to the user here */ }, maxInterval)

請記住重置AJAX調用的時間間隔,因爲由於頁面沒有被重新加載,所以不會被重置。

請注意,URL映射只能在非AJAX請求中發揮作用,因爲頁面沒有被重新加載,因此沒有顯示頁面。你將不得不使用@Gregg用來處理AJAX請求的東西。