webview HttpClient 怎么保持会话session统一

 
cookies session均为key---value的形式展示,
 1.    session是存储在服务端,并有一块区域控件存储用户信息,主要是为了判断该用户是否登录,在客户端采用httpClient/HttpUrlConnection进行登录请求的时候,传过去的username=“ccc” 服务端中的session进行判断是否存在改sessionId,以及value,不存在代表改用户不曾登录,服务器会自动生成唯一的sessionId其为key,传过来的ccc则为value,key="sessionId" value=“ccc”,成功请求后下次进行http请求的时候请求头会带上这个sessionId进行跟服务端的session存储区域进行判断,是否登录过,登录过则返回成功,未登录则从新分配。判断类似map集合,通过map.get(sessionId)是否等于ccc。
   
2.     问题:httpClient中的cookie管理看什么?
3.     CookieManager 是管理webview的,session是存储在cookies中,httpclient登录到服务器的时候,从http的cookie中取出sessionId放入到webview中(同步cookie),webview访问业务的时候,由于sessionId一致,服务器会认为该用户已登录。
 
Cooki的获取:
1 1
2 2
3 
4 CookieManager cm = CookieManager.getInstance();
5 String Cookiestr = cm.getCookie(url);

 

Cookie的同步:
1 Cookie的同步:
2 
3 
4 CookieSyncManager.createInstance(this);
5 
6 
7 CookieSyncManager.getInstance().sync();
 
清除Cookie:
1 清除Cookie:
2 
3      CookieManager.getInstance().removeSessionCookie();
4    或:
5 CookieManager.getInstance().removeAllCookies();
 
只要允许js就不能同步成功。原因可能是因为允许js就能通过ajax跨域获取数据。可能处于安全考虑所以被禁止
 
httpclient与webview需要进行cookie 共享,因为如果不共享,那么假设你在httpclient进行了登录,然后用webview里打开那些login之后才能看的page
 
  1.  1 - DefaultHttpClient httpclient=....;
     2 - String toUrl="https://cap.cityu.edu.hk/studentlan/details.aspx.....";
     3 -
     4 - List<Cookie> cookies = httpclient.getCookieStore().getCookies();
     5 -
     6 - if (! cookies.isEmpty()){
     7 -     CookieSyncManager.createInstance(this);
     8 -     CookieManager cookieManager = CookieManager.getInstance();
     9 -         //sync all the cookies in the httpclient with the webview by generating cookie string
    10 -     for (Cookie cookie : cookies){
    11 -         String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();
    12 -         cookieManager.setCookie(toUrl, cookieString);
    13 -         CookieSyncManager.getInstance().sync();
    14 -     }
    15 - }

     

1 SharedPreferences spf = getSharedPreferences("Cookie", Context.MODE_PRIVATE);
2         CookieSyncManager.createInstance(this);
3         CookieManager cookieManager = CookieManager.getInstance();
4         String cookieString = spf.getString("cookieString", "");
5         cookieManager.setCookie(url, cookieString);
6         CookieSyncManager.getInstance().sync();
7 
8         webview.loadUrl(url);

 

 1   public static void addLoginCookie() {
 2         //登录成功后 重新设置webviewcookie信息 用来保持session一致...................start
 3         CookieSyncManager.createInstance(App.getInstance().getApplicationContext());
 4         CookieManager cookieManager = CookieManager.getInstance();
 5 
 6         List<Cookie> cookies = App.getPersistentCookiesList();
 7         for (int i = 0; i < cookies.size(); i++) {
 8             Cookie cookie = cookies.get(i);
 9             String cookieString = cookie.getName() + "=" + cookie.getValue() + "; domain=" + cookie.getDomain();
10             cookieManager.setCookie(URLSet.cookiedomain, cookieString);
11         }
12 
13         CookieSyncManager.getInstance().sync();
14         //..................................................................end
15     }

 

 
1.1 session的概念
 
          在计算机专业术语里:session是指一个终端用户与交互系统进行通信的时间间隔通常指从注册入系统到注销系统之间所经过的时间以及如果需要的话,可能还有一定操作空间。
 
          具体到web应用里的session,大家都做过web开发,这里我就先不提出web里session的定义,先和大伙讲下和session相关的技术背景。
 
          早期的web应用或者说早期的网站都是一种处理静态资源的网站,功能主要是查看文档,看看图片,而现在的web应用和早期的差别已经很大,互联网的网站更准确的定义应该是互联网软件即网站就是软件,网站所代表的软件和早期软件的定义是不一样的,早期的软件都是在单机环境下运行,而互联网的普及让软件和网络技术融合在一起,这就要求网站所代表的软件应该要有一个对事务处理的记忆功能,事务处理的记忆功能就是我们常说的要有状态。而实现web应用技术的核心http协议是一个无状态的协议,http这种设计也许是历史遗留问题,也许无状态的http是最简单也是最有效的通讯方式,但是当网站成为软件后,状态的保持就是一个很重要的功能。
因此在web应用开发里就出现了保持http链接状态的技术:一个是cookie技术,另一种是session技术。
 
          cookie技术是客户端的解决方案(当然随着html5的出现,比cookie更为强劲和安全的技术出现了,但是鉴于html5的普及度不够,就不做本文讨论的内容了),Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。让我们说得更具体一些:当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header);当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置,对于Windows操作系统而言,我们可以从: [系统盘]:\Documents and Settings\[用户名]\Cookies目录中找到存储的Cookie;自此,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。通常,我们可以从很多网站的登录界面中看到“请记住我”这样的选项,如果你勾选了它之后再登录,那么在下一次访问该网站的时候就不需要进行重复而繁琐的登录动作了,而这个功能就是通过Cookie实现的
 
          session技术则是服务端的解决方案,它是通过服务器来保持状态的。由于Session这个词汇包含的语义很多,因此需要在这里明确一下 Session的含义。首先,我们通常都会把Session翻译成会话,因此我们可以把客户端浏览器与服务器之间一系列交互的动作称为一个 Session。从这个语义出发,我们会提到Session持续的时间,会提到在Session过程中进行了什么操作等等;其次,Session指的是服务器端为客户端所开辟的存储空间,在其中保存的信息就是用于保持状态。从这个语义出发,我们则会提到往Session中存放什么内容,如何根据键值从 Session中获取匹配的内容等。要使用Session,第一步当然是创建Session了。那么Session在何时创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。在创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;在Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有Session id;当客户端再次发送请求的时候,会将这个Session id带上,服务器接受到请求之后就会依据Session id找到相应的Session,从而再次使用之。正式这样一个过程,用户的状态也就得以保持了。
 
          由此我们可以得出,session是解决http协议无状态问题的服务端解决方案,它能让客户端和服务端一系列交互动作变成一个完整的事务,能使网站变成一个真正意义上的软件。
 
1.2 cookie与session的关系
          cookie和session的方案虽然分别属于客户端和服务端,但是服务端的session的实现对客户端的cookie有依赖关系的,上面我讲到服务端执行session机制时候会生成session的id值,这个id值会发送给客户端,客户端每次请求都会把这个id值放到http请求的头部发送给服务端,而这个id值在客户端会保存下来,保存的容器就是cookie,因此当我们完全禁掉浏览器的cookie的时候,服务端的session也会不能正常使用(注意:有些资料说ASP解决这个问题,当浏览器的cookie被禁掉,服务端的session任然可以正常使用,ASP我没试验过,但是对于网络上很多用php和jsp编写的网站,我发现禁掉cookie,网站的session都无法正常的访问)
 
1.3 session实现的原理
          java的web容器都实现了session机制,实现的逻辑思想都是一致的,但是具体方案可能会存在一定差异,这里我以tomcat容器为例,探讨下session实现的机制。
下图是tomcat源码里session实现:
 
 
          实现包的路径是:org.apache.catalina.session,tomcat对外提供session调用的接口不在这个实现包里,对外接口是在包javax.servlet.http下的HttpSession,而实现包里的StandardSession是tomcat提供的标准实现,当然对外tomcat不希望用户直接操作StandardSession,而是提供了一个StandardSessionFacade类,tomcat容器里具体操作session的组件是servlet,而servlet操作session是通过StandardSessionFacade进行的,这样就可以防止程序员直接操作StandardSession所带来的安全问题。(StandardSessionFacade使用了设计模式里的Fa?ade(外观)模式,外观模式能让不同逻辑层的组件进行解耦)。
 
实现类里有Manager的类是用来管理session的工具类,它负责创建和销毁session对象,其中ManagerBase是所有session管理工具类的基类,它是一个抽象类,所有具体实现session管理功能的类都要继承这个类,该类有一个受保护的方法,该方法就是创建sessionId值的方法(tomcat的session的id值生成的机制是一个随机数加时间加上jvm的id值,jvm的id值会根据服务器的硬件信息计算得来,因此不同jvm的id值都是唯一的),StandardManager类是tomcat容器里默认的session管理实现类,它会将session的信息存储到web容器所在服务器的内存里。PersistentManagerBase也是继承ManagerBase类,它是所有持久化存储session信息的基类,PersistentManager继承了PersistentManagerBase,但是这个类只是多了一个静态变量和一个getName方法,目前看来意义不大,对于持久化存储session,tomcat还提供了StoreBase的抽象类,它是所有持久化存储session的基类,另外tomcat还给出了文件存储FileStore和数据存储JDBCStore两个实现。
 
1.4 在实际运用中session所带来的问题
           由上面所描述的session实现机制,我们会发现,为了弥补http协议的无状态的特点,服务端会占用一定的内存和cpu用来存储和处理session计算的开销,这也就是tomcat这个的web容器的并发连接那么低(tomcat官方文档里默认的连接数是200)原因之一。因此很多java语言编写的网站,在生产环境里web容器之前会加一个静态资源服务器,例如:apache服务器或nginx服务器,静态资源服务器没有解决http无状态问题的功能,因此部署静态资源的服务器也就不会让出内存或cpu计算资源专门去处理像session这样的功能,这些内存和cpu资源可以更有效的处理每个http请求,因此静态资源服务器的并发连接数更高,所以我们可以让那些没有状态保持要求的请求直接在静态服务器里处理,而要进行状态保持的请求则在java的web容器里进行处理,这样能更好的提升网站的效率。
 
          当下的互联网网站为了提高网站安全性和并发量,服务端的部署的服务器的数量往往是大于或等于两台,多台服务器对外提供的服务是等价的,但是不同的服务器上面肯定会有不同的web容器,由上面的讲述我们知道session的实现机制都是web容器里内部机制,这就导致一个web容器里所生成的session的id值是不同的,因此当一个请求到了A服务器,浏览器得到响应后,客户端存下的是A服务器上所生成的session的id,当在另一个请求分发到了B服务器,B服务器上的web容器是不能识别这个session的id值,更不会有这个sessionID所对应记录下来的信息,这个时候就需要两个不同web容器之间进行session的同步。Tomcat容器有一个官方的解决方案就是使用apache+tomcat+mod_jk方案,当一个web容器里session的信息发生变化后,该web容器会向另一个web容器进行广播,另一个web收到广播后将session信息同步到自己的容器里,这个过程是十分消耗系统资源,当访问量增加会严重影响到网站的效率和稳定性。
 
              我现在所做的网站里有一个解决方案,当用户请求网站的时候会先将请求发送给硬件的负载均衡设备,该设备可以截获客户端发送过来的session的id值,然后我们根据这个id值找到产生这个session的服务器,将请求直接发送给这台服务器。这种解决方案看起来解决了session共享问题,其实结果是将集群系统最终变回了单点系统,如果处理请求的web容器挂掉了,那么用户的相关会话操作也就废掉了。此外,这种做法也干扰了负载均衡服务器的负载均衡的计算,让请求的分发并不是公平的。
 
  一般大型互联公司的网站都是有一个个独立的频道所组成的,例如我们常用的百度,会有百度搜索,百度音乐,百度百科等等,我相信他们不会把这些不同频道都给一个开发团队完成,应该每个频道都是一个独立开发团队,因为每个频道的应用的都是独立的web应用,那么就存在一个跨站点的session同步的问题,跨站点的登录可以使用单点登录的(SSO)的解决方案,但是不管什么解决方案,跨站点的session共享任然是逃避不了的问题。
 
1.5 解决session相关问题的技术方案
由上所述,session一共有两个问题需要解决:
1) session的存储应该独立于web容器,也要独立于部署web容器的服务器;
2)如何进行高效的session同步。
 
在讲到解决这些问题之前,我们首先要考虑下session如何存储才是高效,是存在内存、文件还是数据库了?文件和数据库的存储方式都是将session的数据固化到硬盘上,操作硬盘的方式就是IO,IO操作的效率是远远低于操作内存的数据,因此文件和数据库存储方式是不可取的,所以将session数据存储到内存是最佳的选择。因此最好的解决方案就是使用分布式缓存技术,例如:memcached和redis,将session信息的存储独立出来也是解决session同步问题的方法。
Tomcat的session同步也有使用memcache的解决方案,大家可以参加下面的文章:
 
但是该方案只是解决了同步问题,session机制任然和web容器紧耦合,我们需要一个高效、可扩展的解决方案,那么我们就应该不是简单的把session独立出来存储而是设计一个完全独立的session机制,它既能给每个web应用提供session的功能又可以实现session同步,下面是一篇用zookeeper实现的分布式session方案:
 
自己理解:
 
     客户端首次访问服务器的时候,http请求头是空,服务器检测并响应,如果是空则返回相应的session和对应的唯一sessionId,因为session是
客户端根据http协议(无状态连接)通过session和cookies自动设置,下次客户端再进行http请求的时候,请求头中传入cookies,服务器自动获取并校验,如果是单纯的浏览器,在校验sessionId与服务器设置的超时时间相比,如果超时直接拉取登录,未超时且一致则跳入相应的界面获取相关信息。
 
因为http是无状态协议,而cookie的作用就是为了解决Http协议无状态的缺陷。
session机制则是客户端与服务器之间保持状态的解决方案
 
 
 
1.cookie 是一种发送到客户浏览器的文本串句柄,并保存在客户机硬盘上(设置了有效期),可以用来在某个WEB站点会话间持久的保持数据。
 
2.session其实指的就是访问者从到达某个特定主页到离开为止的那段时间。 Session其实是利用Cookie进行信息处理的,当用户首先进行了请求后,服务端就在用户浏览器上创建了一个Cookie,当这个Session结束时,其实就是意味着这个Cookie就过期了。
注:为这个用户创建的Cookie的名称是aspsessionid。这个Cookie的唯一目的就是为每一个用户提供不同的身份认证。
 
3.cookie和session的共同之处在于:cookie和session都是用来跟踪浏览器用户身份的会话方式。
 
4.cookie 和session的区别是:cookie数据保存在客户端,session数据保存在服务器端。
  简单的说,当你登录一个网站的时候:
 

·         如果web服务器端使用的是session,那么所有的数据都保存在服务器上,客户端每次请求服务器的时候会发送当前会话的sessionid,服务器根据当前sessionid判断相应的用户数据标志,以确定用户是否登录或具有某种权限。由于数据是存储在服务器上面,所以你不能伪造,但是如果你能够获取某个登录用户的 sessionid,用特殊的浏览器伪造该用户的请求也是能够成功的。sessionid是服务器和客户端链接时候随机分配的,一般来说是不会有重复,但如果有大量的并发请求,也不是没有重复的可能性.

 

·         如果浏览器使用的是cookie,那么所有的数据都保存在浏览器端,比如你登录以后,服务器设置了cookie用户名,那么当你再次请求服务器的时候,浏览器会将用户名一块发送给服务器,这些变量有一定的特殊标记。服务器会解释为cookie变量,所以只要不关闭浏览器,那么cookie变量一直是有效的,所以能够保证长时间不掉线。如果你能够截获某个用户的 cookie变量,然后伪造一个数据包发送过去,那么服务器还是认为你是合法的。所以,使用 cookie被攻击的可能性比较大。如果设置了的有效时间,那么它会将 cookie保存在客户端的硬盘上,下次再访问该网站的时候,浏览器先检查有没有 cookie,如果有的话,就读取该 cookie,然后发送给服务器。如果你在机器上面保存了某个论坛 cookie,有效期是一年,如果有人入侵你的机器,将你的  cookie拷走,然后放在他的浏览器的目录下面,那么他登录该网站的时候就是用你的的身份登录的。所以 cookie是可以伪造的。当然,伪造的时候需要主意,直接copy    cookie文件到 cookie目录,浏览器是不认的,他有一个index.dat文件,存储了 cookie文件的建立时间,以及是否有修改,所以你必须先要有该网站的 cookie文件,并且要从保证时间上骗过浏览器

 

5.两个都可以用来存私密的东西,同样也都有有效期的说法,区别在于session是放在服务器上的,过期与否取决于服务期的设定,cookie是存在客户端的,过去与否可以在cookie生成的时候设置进去。

(1)cookie数据存放在客户的浏览器上,session数据放在服务器上
(2)cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,如果主要考虑到安全应当使用session
(3)session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,如果主要考虑到减轻服务器性能方面,应当使用COOKIE
(4)单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。
(5)所以:将登陆信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在COOKIE中
 
 
 
 
 
posted @ 2016-08-16 18:58  全球顶尖骇客  阅读(8548)  评论(0编辑  收藏  举报