禁用Cookie后Session该怎么样使用

禁用Cookie后Session该怎么样使用,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

站在用户的角度思考问题,与客户深入沟通,找到八公山网站设计与八公山网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、成都网站建设、企业官网、英文网站、手机端网站、网站推广、国际域名空间、虚拟空间、企业邮箱。业务覆盖八公山地区。

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的参数追加。

/**
* 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)) {//关键在这里
       // 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);
   }

}

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

/**
* 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);
   
}

代码中会根据是否使用SessionCookie来决定是否要继续,

之后会继承判断可使用的Session tracking Mode里都有哪些,是否包含URL。

禁用Cookie后Session该怎么样使用

在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该怎么样使用
标题网址:http://myzitong.com/article/gohgpj.html