jsessionid是一個Cookie,可以透過在URL後面加上「;jsessionid=xxx」來傳遞「session id」;其中Servlet容器用來記錄使用者session,當我們建立回話時會自動創建,用來記錄使用者的造訪記錄。
首先,JSESSIONID是一個Cookie,Servlet容器(tomcat,jetty)用來記錄使用者session。
什麼時候種下JSESSIONID
#建立會話時,也就是呼叫request.getSession()的時候,關於getSession就不說了。補充幾點是,存取html是不會創建session的,JSP頁面預設是會創建session的,可以在JSP頁裡面關掉自動創建session.
JSESSIONID工作原理:
URL重寫
服務端在記憶體裡建立session,需要種Cookie,除了在request header裡面設定Set- Cookie以外,tomcat等容器有URL重寫機制。這個機制是客戶端Cookie不可用時的一個兜底策略,透過在URL後面加上;jsessionid=xxx來傳遞session id,這樣即使Cookie不可用時,也可以保證session的可用性,但是session暴露在URL裡,本身是不安全的,到這裡基本網路說法都是一致的
但是最關鍵的問題,tomcat怎麼知道客戶端Cookie不可用。我在idea導入tomcat的源碼調試跟踪,不同版本有些出入,大致應該還是一樣的
tomcat有一個org.apache.catalina.connector.Response是Response的落地類,有兩個方法會進行URL重寫,分別是encodeRedirectURL和encodeURL,encodeRedirectURL是重定向時會被調用,encodeURL看起來像是手動調用,所以預設情況,重定向時才會出現URL重寫。兩個方法代碼類似,下面只關注encodeRedirectURL
/** * Encode the session identifier associated with this response * into the specified redirect URL, if necessary. * * @param url URL to be encoded * @return <code>true</code> if the URL was encoded */ @Override public String encodeRedirectURL(String url) { if (isEncodeable(toAbsolute(url))) { return (toEncoded(url, request.getSessionInternal().getIdInternal())); } else { return (url); } }
方法註解寫得很清楚了,如果有必要的話,把session id塞到重定向的URL裡面。再看一下isEncodeable方法,關鍵地方我加了中文註解
/** * Return <code>true</code> if the specified URL should be encoded with * a session identifier. This will be true if all of the following * conditions are met: * <ul> * <li>The request we are responding to asked for a valid session * <li>The requested session ID was not received via a cookie * <li>The specified URL points back to somewhere within the web * application that is responding to this request * </ul> * * @param location Absolute URL to be validated * @return <code>true</code> if the URL should be encoded */ 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; } //这里其实就是网上说的客户端禁用Cookie if (hreq.isRequestedSessionIdFromCookie()) { return false; } // Is URL encoding permitted // servlet3.0后可以在项目web.xml里关掉URL重写,对应tomat7之后 if (!hreq.getServletContext().getEffectiveSessionTrackingModes(). contains(SessionTrackingMode.URL)) { return false; } if (SecurityUtil.isPackageProtectionEnabled()) { return ( AccessController.doPrivileged(new PrivilegedAction<Boolean>() { @Override public Boolean run(){ return Boolean.valueOf(doIsEncodeable(hreq, session, location)); } })).booleanValue(); } else { //这个方法会重写URL return doIsEncodeable(hreq, session, location); } }
其中呼叫Request物件的isRequestedSessionIdFromCookie判斷客戶端Cookie是否可用,裡面邏輯也很簡單,就是讀取request裡面有沒有傳JSESSIONID這個Cookie 。所以網路上有些人說第一次訪問,其實只要客戶端沒有傳JSESSIONID,tomcat都假定Cookie不可用
以上是jsessionid是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!