当前位置: 代码迷 >> Android >> Android开发WordPress的客户端, 登录时Cookie(httpOnly)的有关问题
  详细解决方案

Android开发WordPress的客户端, 登录时Cookie(httpOnly)的有关问题

热度:23   发布时间:2016-05-01 12:02:55.0
Android开发WordPress的客户端, 登录时Cookie(httpOnly)的问题

曾经用Android开发过学校教务系统的登录功能(jsp/tomcat),能够成功模拟出Http请求. 但是WordPress的登录功能实现起来要绕一个弯子. 不能直接用HttpClient来得到cookie.

这位兄弟遇到的问题跟我是一样的?http://hi.baidu.com/xtitman/item/eeaef4c7d4a0e2bc0c0a7b69最后也是成功用socket方法把功能实现了. 其中为如何用socket模拟http的post/get请求消息头以及消息体纠结了几个小时。

My codes are as follows. Please ignore the animation part and focus on the method run() in class MyThread. It's just a demo and I didn't make any post-procession with the result. And if you have any question about this demo, please send an e-mail to [email protected] which I would appreciate much.

?

?

package login.activities;import home.activities.R;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.Socket;import java.net.URLEncoder;import java.net.UnknownHostException;import org.apache.http.HttpEntity;import org.apache.http.HttpResponse;import org.apache.http.client.methods.HttpGet;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.util.EntityUtils;import system.standards.Standards;import android.os.Bundle;import android.util.DisplayMetrics;import android.util.Log;import android.view.View;import android.view.animation.AlphaAnimation;import android.view.animation.Animation;import android.view.animation.Animation.AnimationListener;import android.view.animation.TranslateAnimation;import android.widget.Button;import android.widget.EditText;import android.widget.LinearLayout;import android.widget.RelativeLayout;import android.widget.Toast;public class LoginActivity extends Standards{	private Button leftBall = null;	private Button rightBall = null;	private Button submit = null;	private EditText username = null;	private String usernameText = null;	private EditText password = null;	private String passwordText = null;	private DisplayMetrics metrics = null;	private static final String serverIpAddress = "***.***.***.***";	private static final String encodedUsername = "wordpress_af8ad83c4c8ce7c7f7efddce117a5a74=admin%";	private static final String encodedPassword = "wordpress_logged_in_af8ad83c4c8ce7c7f7efddce117a5a74=admin%";	// private static final String LOGIN_URL =	// "http://atom.student.utwente.nl/wp-login.php";	private static String encodedUsernameText = "";	private static String encodedPasswordText = "";	private boolean isAnimated = false;	@Override	protected void onCreate(Bundle savedInstanceState)	{		// TODO Auto-generated method stub		super.onCreate(savedInstanceState);		setContentView(R.layout.login);		getAllWidgets();		submit.setOnClickListener(new Button.OnClickListener()		{			public void onClick(View arg0)			{				// TODO Auto-generated method stub				usernameText = username.getText().toString();				passwordText = password.getText().toString();				Log.d("DEBUG", "USERNAME: " + usernameText);				Log.d("DEBUG", "PASSWORD: " + passwordText);				doLogin(usernameText, passwordText);			}		});	}	private void doLogin(String usernameText, String passwordText)	{		MyLoginThread myLoginThread = new MyLoginThread(usernameText,				passwordText);		myLoginThread.start();	}	private class MyLoginThread extends Thread	{		private String logUsername = null;		private String logPassword = null;		public MyLoginThread(String logUsername, String logPassword)		{			this.logUsername = logUsername;			this.logPassword = logPassword;		}		@Override		public void run()		{			// TODO Auto-generated method stub			// 首先采用socket方式模拟浏览器发出第一个Post请求访问第一个网页(携带的参数是username和 password, 消息头以及消息体必须遵守post/get的严格格式)			// 之后得到第一个网页的HttpResponse, 从中提取出由服务器加密之后的username和password			// 第一个网页由于返回状态码302因而需要进行重定向到真正的DashBoard即登录成功页面			// 重定向是需要重新发送一个请求, 通过FireBug可以得知需要得到的是GET请求			// 并且携带的cookie是包含上次请求返回的加密之后username和password			// 所以这次模拟的重定向可以直接使用HttpGet, 然后调用httpGet.addHeader("Cookie", 加密之后的用户名 + 加密之后的密码 + 其他信息(是静态的信息, 可以由FireBug探测得知));			// 從而得到真正的DashBoard页面			// 为什么第一次请求需要用底层的socket呢?而不直接使用HttpPost/HttpClient呢?可以通过使用相应方法(getHeaders()?getCookie()?)得到cookies, 而不需要自己来拼串			// 原因是发现第一次的请求返回的cookies, 是 httpOnly的, 采用HttpClient方式遍历headers可以发现是打印不出来的!也就是说不能用上层的这些方法了			// 所以之后采用socket方法模拟POST请求了, 得到的是未经过加工处理的response, 采用String的相应方法拼串可以提取出cookies						try			{				Socket socket = new Socket(serverIpAddress, 80);				BufferedReader br = new BufferedReader(new InputStreamReader(						socket.getInputStream(), "UTF-8"));				OutputStream os = socket.getOutputStream();				StringBuffer sb = new StringBuffer(						"POST /wp-login.php HTTP/1.1\r\n");				sb.append("Host: atom.student.utwente.nl\r\n");				sb.append("Connection: keep-alive\r\n");				sb.append("Content-Length: 114\r\n");				sb.append("Cache-Control: max-age=0\r\n");				sb.append("Origin: http://atom.student.utwente.nl\r\n");				sb.append("User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1\r\n");				sb.append("Content-Type: application/x-www-form-urlencoded\r\n");				sb.append("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n");				sb.append("Referer: http://atom.student.utwente.nl/wp-login.php\r\n");				sb.append("Accept-Encoding: gzip,deflate,sdch");				sb.append("Accept-Language: en,en-US;q=0.8,zh;q=0.6,zh-CN;q=0.4,nl;q=0.2\r\n");				sb.append("Accept-Charset: UTF-8,*;q=0.5\r\n");				sb.append("Cookie: wordpress_polylang=en; wp-settings-1=imgsize%3Dfull%26editor%3Dhtml%26hidetb%3D1%26libraryContent%3Dbrowse; wp-settings-time-1=1357880535; wordpress_test_cookie=WP+Cookie+check\r\n");				sb.append("\r\n");				sb.append(URLEncoder.encode("log", "UTF-8"));				sb.append("=");				sb.append(URLEncoder.encode(logUsername, "UTF-8"));				sb.append("&");				sb.append(URLEncoder.encode("pwd", "UTF-8"));				sb.append("=");				sb.append(URLEncoder.encode(logPassword, "UTF-8"));				sb.append("&");				sb.append(URLEncoder.encode("wp-submit", "UTF-8"));				sb.append("=");				sb.append(URLEncoder.encode("Log In", "UTF-8"));				sb.append("&");				sb.append(URLEncoder.encode("redirect_to", "UTF-8"));				sb.append("=");				sb.append(URLEncoder.encode(						"http://atom.student.utwente.nl/wp-admin/", "UTF-8"));				sb.append("&");				sb.append(URLEncoder.encode("testcookie", "UTF-8"));				sb.append("=");				sb.append(URLEncoder.encode("1", "UTF-8"));				os.write(sb.toString().getBytes());				String tmp = "";				StringBuffer resultBuffer = new StringBuffer();				while ((tmp = br.readLine()) != null)				{					System.out.println(tmp);					resultBuffer.append(tmp);				}				int usernameStartPosition = resultBuffer						.indexOf(encodedUsername) + encodedUsername.length();				int passwordStartPosition = resultBuffer						.indexOf(encodedPassword) + encodedPassword.length();				encodedUsernameText = resultBuffer.substring(						usernameStartPosition, usernameStartPosition + 47);				encodedPasswordText = resultBuffer.substring(						passwordStartPosition, passwordStartPosition + 47);				System.out.println("encodedUsernameText: "						+ encodedUsernameText);				System.out.println("encodedPasswordText: "						+ encodedPasswordText);				os.close();				br.close();				DefaultHttpClient httpClient = new DefaultHttpClient();				HttpGet httpGet = new HttpGet(						"http://atom.student.utwente.nl/wp-admin/");				httpGet.addHeader(						"Cookie",						encodedUsername								+ encodedUsernameText								+ "; wordpress_polylang=en; wp-settings-1=imgsize%3Dfull%26editor%3Dhtml%26hidetb%3D1%26libraryContent%3Dbrowse; wp-settings-time-1=1357880535; wordpress_test_cookie=WP+Cookie+check; "								+ encodedPassword + encodedPasswordText);				HttpResponse httpResponse = null;				httpResponse = httpClient.execute(httpGet);				HttpEntity httpEntity = null;				String resultText = null;				if (httpResponse.getStatusLine().getStatusCode() == 200)				{					System.out.println("LOGIN SUCCEED!");										Toast.makeText(LoginActivity.this,							"LOGIN SUCCEED!", Toast.LENGTH_SHORT)							.show();										httpEntity = httpResponse.getEntity();					resultText = EntityUtils.toString(httpEntity, "UTF-8");					System.out.println(resultText);				} else				{					Toast.makeText(LoginActivity.this,							"Invalid Username or Password!", Toast.LENGTH_SHORT)							.show();				}			} catch (UnknownHostException e)			{				// TODO Auto-generated catch block				e.printStackTrace();			} catch (IOException e)			{				// TODO Auto-generated catch block				e.printStackTrace();			}			super.run();		}	}	private class MyAnimationMoveListener implements AnimationListener	{		@Override		public void onAnimationEnd(Animation animation)		{			// TODO Auto-generated method stub			// clear all animations			leftBall.clearAnimation();			rightBall.clearAnimation();			findViewById(R.id.loginlay3).clearAnimation();			findViewById(R.id.loginlay4).clearAnimation();			findViewById(R.id.loginlay5).clearAnimation();			// widgets translations & invisiable			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(					leftBall.getWidth(), leftBall.getHeight());			// params.leftMargin = (screenWidth / 2 - leftBall.getWidth() -			// screenWidth / 3);			params.addRule(RelativeLayout.LEFT_OF, R.id.loginlay3);			leftBall.setLayoutParams(params);			RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(					rightBall.getWidth(), rightBall.getHeight());			params2.addRule(RelativeLayout.RIGHT_OF, R.id.loginlay3);			rightBall.setLayoutParams(params2);			System.out.println("rightSpace: " + rightBall.getRight());			// rightBall.setLayoutParams(params2);			findViewById(R.id.loginlay3).setVisibility(View.VISIBLE);			findViewById(R.id.loginlay4).setVisibility(View.VISIBLE);			findViewById(R.id.loginlay5).setVisibility(View.VISIBLE);		}		@Override		public void onAnimationRepeat(Animation animation)		{			// TODO Auto-generated method stub		}		@Override		public void onAnimationStart(Animation animation)		{			// TODO Auto-generated method stub		}	}	private class MyAnimationReturnListener implements AnimationListener	{		@Override		public void onAnimationEnd(Animation animation)		{			// TODO Auto-generated method stub			// clear all animations			leftBall.clearAnimation();			rightBall.clearAnimation();			findViewById(R.id.loginlay3).clearAnimation();			findViewById(R.id.loginlay4).clearAnimation();			findViewById(R.id.loginlay5).clearAnimation();			// widgets translations & invisiable			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(					leftBall.getWidth(), leftBall.getHeight());			params.addRule(RelativeLayout.LEFT_OF, R.id.nothing);			leftBall.setLayoutParams(params);			RelativeLayout.LayoutParams params2 = new RelativeLayout.LayoutParams(					rightBall.getWidth(), rightBall.getHeight());			params2.addRule(RelativeLayout.RIGHT_OF, R.id.left_ball);			rightBall.setLayoutParams(params2);			findViewById(R.id.loginlay3).setVisibility(View.INVISIBLE);			findViewById(R.id.loginlay4).setVisibility(View.INVISIBLE);			findViewById(R.id.loginlay5).setVisibility(View.INVISIBLE);		}		@Override		public void onAnimationRepeat(Animation animation)		{			// TODO Auto-generated method stub		}		@Override		public void onAnimationStart(Animation animation)		{			// TODO Auto-generated method stub		}	}	private void startAllWidgetAnimation(boolean hasAnimated)	{		int leftBallTranslation = 0;		int rightBallTranslation = 0;		MyAnimationReturnListener returnListener = new MyAnimationReturnListener();		MyAnimationMoveListener moveListener = new MyAnimationMoveListener();		AlphaAnimation anim3 = null;		Animation anim2 = null;		Animation anim1 = null;		if (false == hasAnimated)		{			leftBallTranslation = -findViewById(R.id.loginlay3).getWidth() / 2;			System.out.println("R.id.loginlay3 width: "					+ findViewById(R.id.loginlay3).getWidth());			rightBallTranslation = -leftBallTranslation;			anim3 = new AlphaAnimation(0.0f, 1.0f);			anim3.setAnimationListener(moveListener);		} else		{			leftBallTranslation = findViewById(R.id.loginlay3).getWidth() / 2;			rightBallTranslation = -leftBallTranslation;			anim3 = new AlphaAnimation(1.0f, 0.0f);			anim3.setAnimationListener(returnListener);		}		anim1 = new TranslateAnimation(0, leftBallTranslation, 0, 0);		anim1.setDuration(2000);		anim1.setFillAfter(true);		anim2 = new TranslateAnimation(0, rightBallTranslation, 0, 0);		anim2.setDuration(2000);		anim2.setFillAfter(true);		// if (false == hasAnimated)		// {		// anim1.setAnimationListener(moveListener);		// anim2.setAnimationListener(moveListener);		// } else		// {		// anim1.setAnimationListener(returnListener);		// anim2.setAnimationListener(returnListener);		// }		leftBall.startAnimation(anim1);		rightBall.startAnimation(anim2);		// edit text animation		anim3.setStartOffset(1000);		anim3.setDuration(1000);		anim3.setFillAfter(true);		// usernameTag & usernameText layer animation		((LinearLayout) findViewById(R.id.loginlay3)).startAnimation(anim3);		// passwordTag & passwordText layer animation		((LinearLayout) findViewById(R.id.loginlay4)).startAnimation(anim3);		// submit button animation		((LinearLayout) findViewById(R.id.loginlay5)).startAnimation(anim3);	}	public void myClickHandler(final View view)	{		int id = view.getId();		if ((id == R.id.left_ball || id == R.id.right_ball)				&& false == isAnimated)		{			// leftBall moves left, rightBall moves right, loginField turns			// visible			startAllWidgetAnimation(false);			isAnimated = true;		} else if (true == isAnimated)		{			// leftBall moves right, rightBall moves left, loginField turns			// invisible, return to initial state			startAllWidgetAnimation(true);			isAnimated = false;		}	}	private void getAllWidgets()	{		metrics = new DisplayMetrics();		getWindowManager().getDefaultDisplay().getMetrics(metrics);		// screenWidth = metrics.widthPixels;		leftBall = (Button) findViewById(R.id.left_ball);		rightBall = (Button) findViewById(R.id.right_ball);		submit = (Button) findViewById(R.id.login_submit);		username = (EditText) findViewById(R.id.username);		password = (EditText) findViewById(R.id.password);	}}
  相关解决方案