Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с авторизацией на сервере 
:(
    Опции темы
alliance00790
Дата 4.5.2013, 19:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 27.2.2013

Репутация: нет
Всего: нет



Здравствуйте. 
Пишу программу, для работы с которой необходимо парсить страницу на сайте и выбирать необходимую информацию.
Столкнулся со следующей проблемой : портал, с которого парсится информация с автоматической авторизацией пользователя.
При просмотре в браузере google chrome информации о cookie написано следующее : В качестве cookie используется phpsessionid. Срок действия - при завершении сеанса браузера.
Проблема в том, что при последовательных get запросах через некоторое время от сервера приходит ответ 401 - не авторизован. После определенного времени можно снова пользоваться запросами, пока снова будем не авторизованы.

Использую стандартные URLConnection. Получаю из заголовка Set-Cookie значение сессии, подставляю в последующие запросы - все равно такая проблема.

код : 
Код

 /**
     * CookieManager is a simple utilty for handling cookies when working
     * with java.net.URL and java.net.URLConnection
     * objects.
     * 
     * 
     *     Cookiemanager cm = new CookieManager();
     *     URL url = new URL("http://www.hccp.org/test/cookieTest.jsp");
     *     
     *      . . . 
     *
     *     // getting cookies:
     *     URLConnection conn = url.openConnection();
     *     conn.connect();
     *
     *     // setting cookies
     *     cm.storeCookies(conn);
     *     cm.setCookies(url.openConnection());
     * 
     *     @author Ian Brown
     *      
     **/

public class CookieManager {
        
    private Map store;

    private static final String SET_COOKIE = "Set-Cookie";
    private static final String COOKIE_VALUE_DELIMITER = ";";
    private static final String PATH = "path";
    private static final String EXPIRES = "expires";
    private static final String DATE_FORMAT = "EEE, dd-MMM-yyyy hh:mm:ss z";
    private static final String SET_COOKIE_SEPARATOR="; ";
    private static final String COOKIE = "Cookie";

    private static final char NAME_VALUE_SEPARATOR = '=';
    private static final char DOT = '.';
    
    private DateFormat dateFormat;

    public CookieManager() {

    store = new HashMap();
    dateFormat = new SimpleDateFormat(DATE_FORMAT);
    }
    

    /**
     * Retrieves and stores cookies returned by the host on the other side
     * of the the open java.net.URLConnection.
     *
     * The connection MUST have been opened using the connect()
     * method or a IOException will be thrown.
     *
     * @param conn a java.net.URLConnection - must be open, or IOException will be thrown
     * @throws java.io.IOException Thrown if conn is not open.
     */
    public void storeCookies(URLConnection conn) throws IOException {
    
    // let's determine the domain from where these cookies are being sent
    String domain = getDomainFromHost(conn.getURL().getHost());
    
    
    Map domainStore; // this is where we will store cookies for this domain
    
    // now let's check the store to see if we have an entry for this domain
    if (store.containsKey(domain)) {
        // we do, so lets retrieve it from the store
        domainStore = (Map)store.get(domain);
    } else {
        // we don't, so let's create it and put it in the store
        domainStore = new HashMap();
        store.put(domain, domainStore);    
    }
    
    
    
    
    // OK, now we are ready to get the cookies out of the URLConnection
    
    String headerName=null;
    for (int i=1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
        if (headerName.equalsIgnoreCase(SET_COOKIE)) {
        Map cookie = new HashMap();
        StringTokenizer st = new StringTokenizer(conn.getHeaderField(i), COOKIE_VALUE_DELIMITER);
        
        // the specification dictates that the first name/value pair
        // in the string is the cookie name and value, so let's handle
        // them as a special case: 
        
        if (st.hasMoreTokens()) {
            String token  = st.nextToken();
            String name = token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR));
            String value = token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length());
            domainStore.put(name, cookie);
            cookie.put(name, value);
        }
    
        while (st.hasMoreTokens()) {
            String token  = st.nextToken();
            if(token.indexOf(NAME_VALUE_SEPARATOR) != -1)
             cookie.put(token.substring(0, token.indexOf(NAME_VALUE_SEPARATOR)).toLowerCase(),
             token.substring(token.indexOf(NAME_VALUE_SEPARATOR) + 1, token.length()));
        }
        }
    }
    }
 

    /**
     * Prior to opening a URLConnection, calling this method will set all
     * unexpired cookies that match the path or subpaths for thi underlying URL
     *
     * The connection MUST NOT have been opened 
     * method or an IOException will be thrown.
     *
     * @param conn a java.net.URLConnection - must NOT be open, or IOException will be thrown
     * @throws java.io.IOException Thrown if conn has already been opened.
     */
    public void setCookies(URLConnection conn) throws IOException {
    
    // let's determine the domain and path to retrieve the appropriate cookies
    URL url = conn.getURL();
    String domain = getDomainFromHost(url.getHost());
    String path = url.getPath();
    
    Map domainStore = (Map)store.get(domain);
    if (domainStore == null) return;
    StringBuffer cookieStringBuffer = new StringBuffer();
    
    Iterator cookieNames = domainStore.keySet().iterator();
    while(cookieNames.hasNext()) {
        String cookieName = (String)cookieNames.next();
        Map cookie = (Map)domainStore.get(cookieName);
        // check cookie to ensure path matches  and cookie is not expired
        // if all is cool, add cookie to header string 
        if (comparePaths((String)cookie.get(PATH), path) && isNotExpired((String)cookie.get(EXPIRES))) {
        cookieStringBuffer.append(cookieName);
        cookieStringBuffer.append("=");
        cookieStringBuffer.append((String)cookie.get(cookieName));
        if (cookieNames.hasNext()) cookieStringBuffer.append(SET_COOKIE_SEPARATOR);
        }
    }
    try {
        conn.setRequestProperty(COOKIE, cookieStringBuffer.toString());
    } catch (java.lang.IllegalStateException ise) {
        IOException ioe = new IOException("Illegal State! Cookies cannot be set on a URLConnection that is already connected. " 
        + "Only call setCookies(java.net.URLConnection) AFTER calling java.net.URLConnection.connect().");
        throw ioe;
    }
    }

    private String getDomainFromHost(String host) {
    if (host.indexOf(DOT) != host.lastIndexOf(DOT)) {
        return host.substring(host.indexOf(DOT) + 1);
    } else {
        return host;
    }
    }

    private boolean isNotExpired(String cookieExpires) {
    if (cookieExpires == null) return true;
    Date now = new Date();
    try {
        return (now.compareTo(dateFormat.parse(cookieExpires))) <= 0;
    } catch (java.text.ParseException pe) {
        pe.printStackTrace();
        return false;
    }
    }

    private boolean comparePaths(String cookiePath, String targetPath) {
    if (cookiePath == null) {
        return true;
    } else if (cookiePath.equals("/")) {
        return true;
    } else if (targetPath.regionMatches(0, cookiePath, 0, cookiePath.length())) {
        return true;
    } else {
        return false;
    }
    
    }
    
    /**
     * Returns a string representation of stored cookies organized by domain.
     */

    public String toString() {
    return store.toString();
    }
    
    public static void main(String[] args) { 
    CookieManager cm = new CookieManager();
    try {
        URL url = new URL("http://www.google.com");
        URLConnection conn = url.openConnection();
        conn.connect();
        cm.storeCookies(conn);
        System.out.println(cm);
        cm.setCookies(url.openConnection());
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    }
    
}
    
    



После нашел в интернете пример с классом CookieHandler

Код

package com.samples.cach;

import java.io.*;
import java.net.*;
import java.util.*;

public class ListCookieHandler extends CookieHandler {

private List<Cookie> cache = new LinkedList();

  /**
   * Сохранение всех cookie, находящихся в заголовках ответа
   * в кеше.
   * @param uri URI источник cookie
   * @param responseHeaders Неизменяемая таблица, преобразованная 
   * в список, представляющий поля заголовка ответа
   */

  public void put(
      URI uri,
      Map<String, List<String>> responseHeaders)
        throws IOException {

    System.out.println("Cache: " + cache);
    List<String> setCookieList =  responseHeaders.get("Set-Cookie");
    if (setCookieList != null) {
      for (String item : setCookieList) {
        Cookie cookie = new Cookie(uri, item);
        // Удаления уже существующих cookie
        // Установка новых щначений
        for (Cookie existingCookie : cache) {
          if((cookie.getURI().equals(
            existingCookie.getURI())) &&
             (cookie.getName().equals(
               existingCookie.getName()))) {
           cache.remove(existingCookie);
           break;
         }
       }
       System.out.println("Adding to cache: " + cookie);
       cache.add(cookie);
     }
   }
 }

 /**
  * Получение всех cookie из кеша, соответствующих 
  * uri в заголовке запроса.
  *
  * @param uri URI для отправки cookie
  * @param requestHeaders Таблица заголовков запроса, преобразованная 
  * список полей, содержащих заголовки запроса
  */

 public Map<String, List<String>> get(URI uri,
     Map<String, List<String>> requestHeaders)
       throws IOException {

   // Получение cookie для соответствующего URI
   // Сохранение в списке, разделенном запятыми 
   StringBuilder cookies = new StringBuilder();
   for (Cookie cookie : cache) {
     // Удаление просроченных cookie
     if (cookie.hasExpired()) {
       cache.remove(cookie);
     } else if (cookie.matches(uri)) {
       if (cookies.length() > 0) {
         cookies.append(", ");
       }
       cookies.append(cookie.toString());
     }
   }

   // Возвращаемая таблица
   Map<String, List<String>> cookieMap =
     new HashMap(requestHeaders);

   // Преобразование StringBuilder в List, для сохранения в таблице
   if (cookies.length() > 0) {
     List list =
       Collections.singletonList(cookies.toString());
     cookieMap.put("Cookie", list);
   }
     System.out.println("Cookies: " + cookieMap);
 return Collections.unmodifiableMap(cookieMap);
 }

}


Код

package com.samples.cach;

import java.net.*;
import java.text.*;
import java.util.*;

public class Cookie {

  String name;
  String value;
  URI uri;
  String domain;
  Date expires;
  String path;

  private static DateFormat expiresFormat1
    = new SimpleDateFormat("E, dd MMM yyyy k:m:s 'GMT'");

  private static DateFormat expiresFormat2
    = new SimpleDateFormat("E, dd-MMM-yyyy k:m:s 'GMT'");

  /**
   * Создание cookie из  URI и полей заголовка
   *
   * @param uri URI для cookie
   * @param header установка атрибутов заголовка
   */
  public Cookie(URI uri, String header) {
    String attributes[] = header.split(";");
    String nameValue = attributes[0].trim();
    this.uri = uri;
    this.name = 
      nameValue.substring(0, nameValue.indexOf('='));
    this.value = 
      nameValue.substring(nameValue.indexOf('=')+1);
    this.path = "/";
    this.domain = uri.getHost();

    for (int i=1; i < attributes.length; i++) {
      nameValue = attributes[i].trim();
      int equals = nameValue.indexOf('=');
      if (equals == -1) {
        continue;
      }
      String name = nameValue.substring(0, equals);
      String value = nameValue.substring(equals+1);
      if (name.equalsIgnoreCase("domain")) {
        String uriDomain = uri.getHost();
        if (uriDomain.equals(value)) {
          this.domain = value;
        } else {
          if (!value.startsWith(".")) {
            value = "." + value;
          }
          uriDomain = uriDomain.substring(
            uriDomain.indexOf('.'));
          if (!uriDomain.equals(value)) {
            throw new IllegalArgumentException(
              "Trying to set foreign cookie");
          }
          this.domain = value;
        }
      } else if (name.equalsIgnoreCase("path")) {
        this.path = value;
      } else if (name.equalsIgnoreCase("expires")) {
        try {
          this.expires = expiresFormat1.parse(value);
        } catch (ParseException e) {
          try {
            this.expires = expiresFormat2.parse(value);
          } catch (ParseException e2) {
            throw new IllegalArgumentException(
              "Bad date format in header: " + value);
          }
        }
      }
    }
  }

  public boolean hasExpired() {
    if (expires == null) {
      return false;
    }
    Date now = new Date();
    return now.after(expires);
  }

  public String getName() {
    return name;
  }

  public URI getURI() {
    return uri;
  }

  /**
   * Проверка срока действия cookie и соответствие URI
   *
   * @param uri URI для проверки 
   * @return true в случае соответствия,  иначе false
   */
  public boolean matches(URI uri) {

    if (hasExpired()) {
      return false;
    }

   String path = uri.getPath();
    if (path == null) {
      path = "/";
    }

    return path.startsWith(this.path);
  }

  public String toString() {
    StringBuilder result = new StringBuilder(name);
    result.append("=");
    result.append(value);
    return result.toString();
  }
}


Код

package com.samples.cach;

import java.net.CookieHandler;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

public class TestCookie {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        
        
           String urlString = "http://java.sun.com";
           CookieHandler.setDefault(new ListCookieHandler());
           URL url = new URL(urlString);
           URLConnection connection = url.openConnection();
           Object obj = connection.getContent();
           url = new URL(urlString);
           connection = url.openConnection();
           obj = connection.getContent();
    }

}



Вижу, что cookie берутся, устанавливаются и зацикливаеются методы put() и get() класса ListCookieHandler, cookie устанавливаются пока не придет опять опять ответ от сервера 401.
Подскажите, пожалуйста, в какую сторону копать ?

Я правильно понимаю, раз сертификат действует в пределах одной сессии, а объект URLConnection является одноразовым, то у меня фактически каждый запрос является отдельным открыванием браузера и получения страницы ? Т.е мои манипуляции бесполезны. Спасибо.

PM MAIL   Вверх
COVD
Дата 6.5.2013, 01:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

Репутация: 11
Всего: 43



Цитата

Я правильно понимаю, раз сертификат действует в пределах одной сессии, а объект URLConnection является одноразовым, то у меня фактически каждый запрос является отдельным открыванием браузера и получения страницы ? Т.е мои манипуляции бесполезны. Спасибо.


"каждый запрос является отдельным открыванием браузера" - нет. ("URLConnection является одноразовым" - это для программиста так выглядит, но он кеширует соединение для многократных запросов, если явно не запретить). 

Запрос никоим образом не может на сервере ассоциироваться с открыванием браузера или с закрытием. И сервер никак не может сам определить "сеанс" браузера. Только косвенно, если, например, в течении некоторого времени больше нет запросов, то сервер может допустить, что браузер закрылся и удалить сессию. "Срок действия - при завершении сеанса браузера" - непонятно, что за этим на самом деле стоит, как определяется "сеанс".

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




[ Время генерации скрипта: 0.0813 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.