Springboot如何去掉URL後面的jsessionid
如何去掉URL後面的jsessionid
url中有Jsessionid生成的原因
jsessionid是標明session的id,它存在於cookie中,一般情況不會出現在url中,服務器會從客戶端的cookie中取出來,但是如果客戶端禁用瞭cookie的話,就要重寫url瞭,顯式的將jsessionid重寫到Url中,方便服務器來通過這個找到session的id。
如果客戶端請求的cookie中不包含JSESSIONID,服務端調用request.getSession()時就會生成並傳遞給客戶端,此次響應頭會包含設置cookie的信息
如果客戶端請求的cookie中包含JSESSIONID,服務端調用request.getSession()時就會根據JSESSIONID進行查找對象,如果能查到就返回,否則就跟沒傳遞JSESSIONID一樣;
解決方式一
springBoot2.0之前版本
在 .yml配置文件中做如下配置
解決方式二
在啟動類中繼承SpringBootServletInitializer,然後重寫這個方法 (此方法在springBoot2.0之前版本沒有起作用,暫時做記錄)
public void onStartup(ServletContext servletContext) throws ServletException { super.onStartup(servletContext); // This will set to use COOKIE only servletContext.setSessionTrackingModes( Collections.singleton(SessionTrackingMode.COOKIE) ); // This will prevent any JS on the page from accessing the // cookie - it will only be used/accessed by the HTTP transport // mechanism in use SessionCookieConfig sessionCookieConfig = servletContext.getSessionCookieConfig(); sessionCookieConfig.setHttpOnly(true); }
Java關於jsessionid和URL
在寫JSP程序時,經常發現url中有一個jsessionid參數,在刷新之後就消失瞭。一些人認為這是個一個BUG。
這不是一個bug。當一個新的session被創建時,server並不確定客戶端是否支持cookies,所以它生成瞭一個cookie,就是URL中jsessionid的值。當客戶端在第二次帶著cookie返回時,服務器就知道jsessionid不是必須的,所以就會刪掉它。如果客戶端沒有帶著cookie返回,服務器就會繼續在url中添加jsessionid參數。
但是現在幾乎很難想象瀏覽器會不支持cookie。jsessionid參數也可能會給SEO和安全帶來一定問題。
對SEO的沖擊
有些搜索引擎可能會懲罰(找不到更好的詞形容)那些具有多個不同url但內容相同的網站。因為sessionid是唯一的,所以多個搜索機器人將返回相同的內容但url不同。
這是一個嚴重的問題。我們試一下用google搜索inurl:;jsessionid,Google的搜索結果:About 211,000,000 results (0.25 seconds)
安全問題
在url中包含sessionId不是一個明智之舉,這將為攻擊者提供便利。
解決之道
不幸的是Servlet Specification和Servlet Containers中並未提供一個標準的方法去禁止在url中帶jsessionid。
不過我們可以通過servlet filter去解決這個問題。
package com.lgete.web.filter; import java.io.IOException; import javax.servlet.*; import javax.servlet.http.*; /** * @author Zhu Jia <a * href="mailto:[email protected]" rel="external nofollow" >[email protected]</a> * */ public class URLSessionFilter implements Filter { public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (!(request instanceof HttpServletRequest)) { chain.doFilter(request, response); return; } HttpServletResponse httpResponse = (HttpServletResponse) response; HttpServletResponseWrapper wrappedResponse = new HttpServletResponseWrapper( httpResponse) { public String encodeRedirectUrl(String url) { return url; } public String encodeRedirectURL(String url) { return url; } public String encodeUrl(String url) { return url; } public String encodeURL(String url) { return url; } }; chain.doFilter(request, wrappedResponse); } public void init(FilterConfig filterConfig) { } public void destroy() { } }
在web.xml中添加以下內容:
<filter> <filter-name>URLSessionFilter</filter-name> <filter-class>zj.web.filter.URLSessionFilter</filter-class> </filter> <filter-mapping> <filter-name>URLSessionFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- SSM項目使用攔截器實現登錄驗證功能
- Java過濾器doFilter裡chain.doFilter()函數的理解
- Java Session會話追蹤原理深入分析
- java web項目Session獲取不到問題及解決
- springboot簡單實現單點登錄的示例代碼