登录后丢失会话

时间:2012-10-17 16:49:07

标签: java login

我正在构建一个需要登录某个页面并进行导航的应用程序。我可以登录,前提是响应中包含一个标识它的字符串。但是当我导航到第二页时,我无法将该页面视为已登录用户,仅作为匿名用户。

我会提供我的代码:

import java.net.*;
import java.security.*;
import java.security.cert.*;
import javax.net.ssl.*;
import java.io.*;
import java.util.*;

public class PostTest {
    static HttpsURLConnection conn = null;
    static String sessionId = null;
    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    public static void main(String[] args) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
            SSLContext.setDefault(ctx);


            String data = URLEncoder.encode("txtUserName", "UTF-8") + "=" + URLEncoder.encode(/*username*/, "UTF-8");
            data += "&" + URLEncoder.encode("txtPassword", "UTF-8") + "=" + URLEncoder.encode(/*password*/", "UTF-8");
            data += "&" + URLEncoder.encode("envia", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8");

            connectToSSL(/*login url*/);

                    //throws java.lang.IllegalStateException: Already connected
            conn.setDoOutput(true); 

            OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
            wr.write(data);
            wr.flush();

            BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            String resposta = "";
            while((line = rd.readLine()) != null) {
                resposta += line + "\n";
            }
            System.out.println("valid login -> " + resposta.contains(/*string that assures me I'm looged in*/));

            connectToSSL(/*first navigation page*/);

            rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            while((line = rd.readLine()) != null) {
                System.out.println(line);
            }


        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    private static void connectToSSL(String address) {
        try {
            URL url = new URL(address);
            conn = (HttpsURLConnection) url.openConnection();
            conn.setHostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String arg0, SSLSession arg1) {
                    return true;
                }
            });
                    if(sessionId == null) {
                            sessionId = conn.getHeaderField("Set-Cookie");
                    }
        } catch(Exception ex) {
            ex.printStackTrace();
        }
    }

}

任何进一步的信息,请问。

4 个答案:

答案 0 :(得分:2)

connectToSSL中,您每次都要打开一个新连接。在第二个连接中,它不具有第一次连接的任何属性。

您可能希望在第一次登录连接后设置获取一些令牌/ cookie值,并在后续调用中使用相同的值。例如

首次连接后:

      String sessionId = conn.getHeaderField("Set-Cookie");

在后续连接中:

     conn.setRequestProperty("Cookie", sessionId );

答案 1 :(得分:0)

看一下Apache Commons项目HttpClient。它将帮助您完成您想要完成的任务。您需要比URL类复杂得多的时间。它需要维护大量信息,以便从一个身份验证请求转到后续经过身份验证的请求。

答案 2 :(得分:0)

您正在访问的网站可能使用Cookie来识别登录的会话。您需要保存第一个请求中设置的cookie,并在后续请求中发送它们。

如果您使用的是HttpsUrlConnection,请参阅Cookie Managementjava.net.CookieManager。另一个选择是Apache HttpComponents默认情况下进行cookie管理。

答案 3 :(得分:0)

http是无状态协议。 保留状态(会话)存储从服务器收到的cookie。 List<String> cookies = conn.getHeaderFields().get("Set-Cookie");

在后续请求中将它们发送到服务器

for (String cookie : cookies) {

//remove expires and path from cookie

String cookieValue=cookie.substring(0, cookie.indexOf(';');    conn.addRequestProperty("Cookie",cookieValue);
}

OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());

wr.write(data);