欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

禁用Cookie后,Session怎么样使用

发布时间:2023/12/3 69 豆豆
生活随笔 收集整理的这篇文章主要介绍了 禁用Cookie后,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 上一个类似于jsessionid=xxxx这样的参数,在服务端解析时,获取到jsessionid对应的值,并根据其获取到对应的Session对象,从而保证了交互状态一致。

一句话就说明白了。

但这一句话背后,有一些事情还是需要注意的,

例如,我们可以自己在url后面写上jsessionid=当前session的id值。这种类似于硬编码,因为服务端获取这个session的id是通过jsessionid这个参数名来获取的,而这个参数我们在前一篇文章中了解到,是可以配置的,当改了之后,后面的sessionId就获取不到了。

其次,为了保证各类url规则的一致,服务端提供了response API来处理,只需要直接使用,就可以完成jsessionid的参数追加。

我们看代码中的实现逻辑:

/*** 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*/ 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。

 

创作挑战赛新人创作奖励来咯,坚持创作打卡瓜分现金大奖

总结

以上是生活随笔为你收集整理的禁用Cookie后,Session怎么样使用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。