• 技术文章 >常见问题

    jsessionid是什么

    anonymityanonymity2020-09-10 13:23:24原创15715

    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中文网其它相关文章!

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:jsessionid是什么
    上一篇:什么是编程? 下一篇:什么是中间件?
    php中文网线上培训班

    相关文章推荐

    • 急用snoopy抓取EMS验证码,远程模拟查询单号,无法获取JSessionID的有关问题• 急:用snoopy抓取EMS验证码,远程模拟查询单号,无法获取JSessionID的问题?• Java Web是什么

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网