禁用Cookie后Session該怎么樣使用,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。
站在用戶的角度思考問題,與客戶深入溝通,找到八公山網(wǎng)站設(shè)計與八公山網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、國際域名空間、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋八公山地區(qū)。
Session在瀏覽器關(guān)閉之后就失效
其實本質(zhì)上是瀏覽器在關(guān)閉之后,應(yīng)用對應(yīng)的SessionCookie被清除了,再次打開瀏覽器請求應(yīng)用時,之前的SessionId對應(yīng)的Cookie不存在,所以就會重新創(chuàng)建一個Session。而服務(wù)端原來的Session其實還是存在的,只是沒人與之對應(yīng),就默默的等著超時時間一到,被清除了。
而對于Cookie,我們都知道其是瀏覽器保存客戶端本地的,安全問題暫且不說,但Cookie是可以在瀏覽器中配置后關(guān)閉的。關(guān)閉之后,服務(wù)器就不能再向瀏覽器寫Cookie的,此時我們基于SessionCookie的實現(xiàn)方式就遇到了問題。
雖然每一次仍然通過response將Set-Cookie添加到header里,但發(fā)到瀏覽器的時候,不能再寫Cookie,后續(xù)的請求依然是重新發(fā)一個sessionId為null的請求,導(dǎo)致每次仍是重新創(chuàng)建session對象,并沒有解決交互狀態(tài)的問題。
為了解決這個問題,服務(wù)器提供了另外一種方式:
URL重寫,即英文的URLrewrite。
這一方式,其本質(zhì)上是在每次請求的url后面append 上一個類似于jsessionid=xxxx這樣的參數(shù),在服務(wù)端解析時,獲取到j(luò)sessionid對應(yīng)的值,并根據(jù)其獲取到對應(yīng)的Session對象,從而保證了交互狀態(tài)一致。
一句話就說明白了。
但這一句話背后,有一些事情還是需要注意的,
例如,我們可以自己在url后面寫上jsessionid=當(dāng)前session的id值。這種類似于硬編碼,因為服務(wù)端獲取這個session的id是通過jsessionid這個參數(shù)名來獲取的,而這個參數(shù)我們在前一篇文章中了解到,是可以配置的,當(dāng)改了之后,后面的sessionId就獲取不到了。
其次,為了保證各類url規(guī)則的一致,服務(wù)端提供了response API來處理,只需要直接使用,就可以完成jsessionid的參數(shù)追加。
/**
* Encode the session identifier associated with this response
* into the specified URL, if necessary.
*
* @param url URL to be encoded
*/
@Override
public String encodeURL(String url) {
String absolute;
try {
absolute = toAbsolute(url);
} catch (IllegalArgumentException iae) {
// Relative URL
return url;
}
if (isEncodeable(absolute)) {//關(guān)鍵在這里
// W3c spec clearly said
if (url.equalsIgnoreCase("")) {
url = absolute;
} else if (url.equals(absolute) && !hasPath(url)) {
url += '/';
}
return (toEncoded(url, request.getSessionInternal().getIdInternal()));
} else {
return (url);
}
}
我們看代碼中的實現(xiàn)邏輯:
/**
* Return true
if the specified URL should be encoded with
* a session identifier. This will be true if all of the following
* conditions are met:
*
* - The request we are responding to asked for a valid session
* - The requested session ID was not received via a cookie
* - The specified URL points back to somewhere within the web
* application that is responding to this request
*
*
* @param location Absolute URL to be validated
*/
protected boolean isEncodeable(final String location) {
if (location == null) {
return (false);
}
// Is this an intra-document reference?
if (location.startsWith("#")) {
return (false);
}
// Are we in a valid session that is not using cookies?
final Request hreq = request;
final Session session = hreq.getSessionInternal(false);
if (session == null) {
return (false);
}
if (hreq.isRequestedSessionIdFromCookie()) {
return (false);
}
// Is URL encoding permitted
if (!hreq.getServletContext().getEffectiveSessionTrackingModes().contains(SessionTrackingMode.URL)) {
return false;
}
return doIsEncodeable(hreq, session, location);
}
代碼中會根據(jù)是否使用SessionCookie來決定是否要繼續(xù),
之后會繼承判斷可使用的Session tracking Mode里都有哪些,是否包含URL。
在doIsEncodeable方法中,最終實現(xiàn)是這一行代碼
String tok = ";" +
SessionConfig.getSessionUriParamName(request.getContext()) +
"=" + session.getIdInternal();
也就是我們上面提到的硬編碼jsessionid到url后面不太好的原因,這里就是在讀取它的配置。
public static String getSessionUriParamName(Context context) {
String result = getConfiguredSessionCookieName(context);
if (result == null) {
result = DEFAULT_SESSION_PARAMETER_NAME;
}
return result;
}
另外,我們上面提到的Session tracking Mode,是在Tomcat啟動的時候判斷的,而服務(wù)端并不可能得知以后要連接的瀏覽器中,哪些是不允許Cookie的,所以對于Sesion tracking mode,URL無論如何都是可以使用的,而Session cookie是否要使用,是通過在Context組件中配置的其cookies屬性為false時禁止的
private void populateSessionTrackingModes() {
// URL re-writing is always enabled by default
defaultSessionTrackingModes = EnumSet.of(SessionTrackingMode.URL);
supportedSessionTrackingModes = EnumSet.of(SessionTrackingMode.URL);
if (context.getCookies()){ //此處讀取Context組件的cookies配置,如果為false,則不使用SessionCookie
defaultSessionTrackingModes.add(SessionTrackingMode.COOKIE);
supportedSessionTrackingModes.add(SessionTrackingMode.COOKIE); }
總結(jié)下,即為了防止客戶端禁用Cookie導(dǎo)致的Session狀態(tài)不一致的情況,我們可以采用UrlRewrite的方式來保證。
這一過程,我們可以使用response的encodeURL方法來使sessionid添加到url后面,不過是需要先在Context組件中聲明不使用cookies。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。