httpclient cookie使用介绍

COOKIE的处理

session的保持是通过cookie来维持的,所以如果用户有勾选X天免登陆,这个session就X天内一直有效,就是通过这个cookie来维持。
如果没有选中x天免登陆,基本上就是本次才能保持session,下次打开浏览器就要重新登陆了。所以在web安全里,黑客通过XSS,最终目的就是获取cookie,从免登陆直接进入系统
这次要讲的是得到用户cookie后,免登陆,用httpclient保持原来session访问原本一定要登陆才能做的事情。

本文目的是,得到用户cookie后,免登陆,用httpclient保持原来session访问原本一定要登陆才能做的事情
HttpClient 4.x库可以自己处理Cookie
有两种方法来添加cookie
通过httpclient.setCookieStore(cookieStore)
通过httpGet或者httpPost的addHeader(new BasicHeader("Cookie",cookie));

第一种方法

httpClient是否在下次请求中携带从服务器请求带来的Cookie,完全是有设置决定的。
httpclient.getParams.setParameter(ClientPNames.COOKIE_POLICY,CookiePolicy.BEST_MATCH或者CookiePolicy.BROWSER_COMPATIBILITY。如果设置为Cookie策略为BEST_MATCH,或者BROWER_COMPATIBILITY的话,HttpClient会在请求中携带有服务器返回的Cookie。
如果不设置,应该需要手动添加CookieStore,才会保持session.
如果设置为Cookie策略为默认的话,没设置,则需要手动通过httpclient.setCookieStore(cookieStore)去设置。
note: 如果用的是同一个HttpClient(上下两个请求用同一个httpclient对象。
且没去手动连接释放掉client.getConnectionManager().shutdown();)!
都不用去设置cookie的ClientPNames.COOKIE_POLICY。httpClient都是会保留cookie的!

void main(){
 CookieStore cookieStore = new BasicCookieStore();
 //---将cookie设置到httpclient中---//
 CloseableHttpClient HttpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
 try{
  HttpPost post = new HttpPost(”http://www.baidu.com");
  BasicClientCookie cookie = new BasicClientCookie("name","zhaoke");
  cookie.setVersion(0);
  cookie.setPath("/");
  cookie.setDomain("www.baidu.com");//设置范围
  cookeStore.addCookie(cookie);
  
   httpClient.execute(post);
   List<Cookie> cookies = cookieStore.getCookies();
   for(Cookie cook: cookies){
      System.out.println("Local cookie:"+cookies.get(i));
   } 
 }catch(Exception e){
  e.printStackTrace();
 }finally{
  httpClient.close();
 }
}

第二种方法

通过Header去设置cookie
我们首先要得到一个登陆的cookie,免登陆访问,可以用浏览器登陆,然后F12通过console执行document.cookie得到cookie
用这个cookie,在访问的时候,设置httpGet或者httpPost的addHeader(new BasicHeader("Cookie",cookie));就可以免登陆访问

COOKIE自定义

实际使用中client的过程中,会遇到一种情况,如cookie的key为空的,此时默认的cookie的策略处理cookie是会报错的。
这是可以通过重写cookiestore策略来解决
private static void setCustomCookieSpec(HttpClientBuilder builder){
  CookieSpecProvider easySpecProvider = new CookieSpecProvider(){
    public org.apache.http.cookie.CookeSpec create(HttpContext context){
      return new BrowserCompatSpec(){
        public void validate(Cookie cookie,CookieOrigin prigin) throws Exeption{  }
       
        protected List<Cookie> parse(final HeaderElement[] elems,final CookieOrigin origin) throw Exception{
         final List<Cookie> cookies = new ArrayList<cookie>(elems.length);
         for(final HeaderElement headerelement: elems){
           String name = headerelement.getName();
           String value = headerelement.getValue();
         } 
         if(value==null){ continue; }
         if(name==null || name.length()==0){ throw new MalformedCookieException("Cookie name may not be empty"); }
         final BasicClientCookie cookie = new BasicClientCookie(name,value);
         cookie.setPath(getDefaultPath(origin));
         cookie.setDomain(getDefaultDomain(origin));
        // cycle through the paramters
         final NameValuePair attribs = headerelement.getParameter();
         for(int j=attribute.length-1;j>=0;j--){
           final NameValuePair attrib = attribs[j];
           final String s = attrib.getName().toLowerCase(Locale.ENGLISH);
           cookie.setAttribute(s,attrib.getValue());
           final CookieAttributeHandler handler = findAttribHandler(s);
           if(handler!=null){ handler.parse(cookie,attrib.getValue()); }
         } 
        cookies.add(cookie);
       }
      }
     return cookies;
   }
 };
}

Registry<CookieSpecProvider> r = RegistryBuilder
            .<CookieSpecProvider> create()
            .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory())
            .register(CookieSpecs.BROWSER_COMPATIBILITY, new BrowserCompatSpecFactory())
            .register("easy", easySpecProvider).build();
builder.setDefaultCookieSpecRegistry(r);