免费做网站的好不好,寿光哪里做网站,网站维护与建设实训心得,网站多网合一转载自 禁用Cookie后#xff0c;Session怎么样使用
在上篇中更多的是在分析通过Session Cookie这一方式#xff0c;在每次请求时都将
sessionId以Cookie的形式发到服务端#xff0c;来保持一致。这也是许多人印象中的
Session在浏览器关闭之后就失效这一说法的来源。
其…转载自 禁用Cookie后Session怎么样使用
在上篇中更多的是在分析通过Session Cookie这一方式在每次请求时都将
sessionId以Cookie的形式发到服务端来保持一致。这也是许多人印象中的
Session在浏览器关闭之后就失效这一说法的来源。
其实本质上是浏览器在关闭之后应用对应的SessionCookie被清除了再次打开浏览器请求应用时之前的SessionId对应的Cookie不存在所以就会重新创建一个Session。而服务端原来的Session其实还是存在的只是没人与之对应就默默的等着超时时间一到被清除了。
而对于Cookie我们都知道其是浏览器保存客户端本地的安全问题暂且不说但Cookie是可以在浏览器中配置后关闭的。关闭之后服务器就不能再向浏览器写Cookie的此时我们基于SessionCookie的实现方式就遇到了问题。
虽然每一次仍然通过response将Set-Cookie添加到header里但发到浏览器的时候不能再写Cookie后续的请求依然是重新发一个sessionId为null的请求导致每次仍是重新创建session对象并没有解决交互状态的问题。
为了解决这个问题服务器提供了另外一种方式 URL重写即英文的URLrewrite。 这一方式其本质上是在每次请求的url后面append 上一个类似于jsessionidxxxx这样的参数在服务端解析时获取到jsessionid对应的值并根据其获取到对应的Session对象从而保证了交互状态一致。
一句话就说明白了。
但这一句话背后有一些事情还是需要注意的
例如我们可以自己在url后面写上jsessionid当前session的id值。这种类似于硬编码因为服务端获取这个session的id是通过jsessionid这个参数名来获取的而这个参数我们在前一篇文章中了解到是可以配置的当改了之后后面的sessionId就获取不到了。
其次为了保证各类url规则的一致服务端提供了response API来处理只需要直接使用就可以完成jsessionid的参数追加。
我们看代码中的实现逻辑
/*** Return codetrue/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* liThe request we are responding to asked for a valid session* liThe requested session ID was not received via a cookie* liThe specified URL points back to somewhere within the web* application that is responding to this request* /ul** 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 permittedif (!hreq.getServletContext().getEffectiveSessionTrackingModes().contains(SessionTrackingMode.URL)) {return false;}return doIsEncodeable(hreq, session, location);}
代码中会根据是否使用SessionCookie来决定是否要继续
之后会继承判断可使用的Session tracking Mode里都有哪些是否包含URL。 在doIsEncodeable方法中最终实现是这一行代码 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启动的时候判断的而服务端并不可能得知以后要连接的浏览器中哪些是不允许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); } 总结下即为了防止客户端禁用Cookie导致的Session状态不一致的情况我们可以采用UrlRewrite的方式来保证。
这一过程我们可以使用response的encodeURL方法来使sessionid添加到url后面不过是需要先在Context组件中声明不使用cookies。