使用HttpClient登录微博开放平台,获取授权code

本文介绍如何利用HttpClient直接实现微博开放平台的登录,以获取授权code。由于官方SDK存在不便,作者选择自定义HttpClient代码实现,文中包含详细步骤及关键代码示例。
摘要由CSDN通过智能技术生成

最近需要使用微博开放平台的一些功能,由于官方sdk略坑,故决定自己写个HttpClient来模拟获取授权code。不多说,直接上代码。

首先配置微博开放平台基本参数。

	private static String clientId = "你的clientId";
	private static String redirectURI = "你的回调地址";
	private static String url = "https://api.weibo.com/oauth2/authorize";
	private static String userId = "你的账号";
	private static String passwd = "你的密码";
	private static String appkey = null;

	private static HttpClient client = HttpClients.createDefault();
	private static HttpResponse response = null;
	private static HttpGet httpGet = null;
	private static HttpEntity entity = null;

	private static ScriptEngineManager sem = new ScriptEngineManager();
	private static ScriptEngine se = sem.getEngineByName("javascript");
	private static String getJS() {
		return FileUtil.getString(PathKit.getRootClassPath() + File.separator + "sina.js", "UTF-8");
	}

	static {
		try {
			se.eval(getJS());
		} catch (ScriptException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
然后获取需要授权的对应的Appkey,后面授权需要用到

/**
	 * 获取AppKey
	 * 
	 * @return
	 */
	public static String getAppKey() {
		httpGet = new HttpGet(url + "?withOfficalFlag=0&response_type=code&isLoginSina=0&redirect_uri=" + redirectURI
				+ "&userId=" + userId + "&client_id=" + clientId);
		httpGet.setHeader("Referer",
				url + "?withOfficalFlag=0&passwd=" + passwd
						+ "&action=submit&response_type=code&isLoginSina=0&redirect_uri=" + redirectURI + "&userId="
						+ userId + "&client_id=" + clientId);
		httpGet.setHeader("Host", "login.sina.com.cn");
		httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0");

		try {
			response = client.execute(httpGet);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

		if (response == null) {
			return appkey;
		}
		entity = response.getEntity();

		try {
			// 执行回调函数
			String preloginCallBack = EntityUtils.toString(entity);
			int index = preloginCallBack.indexOf("http://app.weibo.com/t/feed/");
			String temp = preloginCallBack.substring(index + 28, index + 34);
			appkey = temp;
		} catch (Exception e) {
			// TODO: handle exception
		}
		return appkey;
	}
然后获取加密后的用户名,登录的时候需要用到

	/**
	 * 获取加密后的用户名
	 * 
	 * @return
	 */
	public static String getSu() {
		Invocable inv = (Invocable) se;
		try {
			String su = (String) inv.invokeFunction("getUs", userId);
			return su;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
接着我们登录微博。

/**
	 * 登录, 传入加密的用户名
	 * 
	 * @param su
	 * @return
	 */
	public static JSONObject login(String su) {
		Invocable inv = (Invocable) se;
		httpGet = new HttpGet(
				"https://login.sina.com.cn/sso/prelogin.php?entry=openapi&callback=sinaSSOController.preloginCallBack&su="
						+ su + "&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.18)&_=" + System.currentTimeMillis());

		httpGet.setHeader("Referer",
				url + "?withOfficalFlag=0&passwd=" + passwd
						+ "&action=submit&response_type=code&isLoginSina=0&redirect_uri=" + redirectURI + "&userId="
						+ userId + "&client_id=" + clientId);
		httpGet.setHeader("Host", "login.sina.com.cn");
		httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0");
		try {
			response = client.execute(httpGet);

			if (response != null) {
				entity = response.getEntity();
				// 执行回调函数
				String preloginCallBack = EntityUtils.toString(entity);
				se.eval(preloginCallBack);
				// 执行自己加入的获取密码方法
				String sp = (String) inv.invokeFunction("getPass", passwd);
				
				preloginCallBack = preloginCallBack.replace("sinaSSOController.preloginCallBack(", "");
				preloginCallBack = preloginCallBack.substring(0, preloginCallBack.length() - 1);
				JSONObject obj = JSON.parseObject(preloginCallBack);

				// 拼凑登陆数据
				HttpPost loginPost = new HttpPost(
						"https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.18)&_" + System.currentTimeMillis()
								+ "&openapilogin=qrcode");
				List<NameValuePair> formData = new ArrayList<>();
				// 应用的App Key
				formData.add(new BasicNameValuePair("entry", "openapi"));
				// 应用的重定向页面
				formData.add(new BasicNameValuePair("gateway", "1"));
				// 模拟登录参数
				// 开发者或测试账号的用户名和密码
				formData.add(new BasicNameValuePair("from", ""));
				formData.add(new BasicNameValuePair("savestate", "0"));
				formData.add(new BasicNameValuePair("useticket", "1"));
				formData.add(new BasicNameValuePair("pagerefer", url));
				formData.add(new BasicNameValuePair("ct", "1800"));
				formData.add(new BasicNameValuePair("s", "1"));
				formData.add(new BasicNameValuePair("vsnf", "1"));
				formData.add(new BasicNameValuePair("vsnval", ""));
				formData.add(new BasicNameValuePair("door", ""));
				formData.add(new BasicNameValuePair("appkey", appkey));
				formData.add(new BasicNameValuePair("su", su));
				formData.add(new BasicNameValuePair("service", "miniblog"));
				formData.add(new BasicNameValuePair("servertime", obj.getString("servertime")));
				formData.add(new BasicNameValuePair("nonce", obj.getString("nonce")));
				formData.add(new BasicNameValuePair("pwencode", "rsa2"));
				formData.add(new BasicNameValuePair("rsakv", obj.getString("rsakv")));
				formData.add(new BasicNameValuePair("sp", sp));
				formData.add(new BasicNameValuePair("sr", "1920*1080"));
				formData.add(new BasicNameValuePair("encoding", "UTF-8"));
				formData.add(new BasicNameValuePair("cdult", "2"));
				formData.add(new BasicNameValuePair("domain", "weibo.com"));
				formData.add(new BasicNameValuePair("prelt", "201"));
				formData.add(new BasicNameValuePair("returntype", "TEXT"));
				loginPost.setEntity(new UrlEncodedFormEntity(formData, Consts.UTF_8));

				loginPost.setHeader("Referer",
						url + "?withOfficalFlag=0&passwd=" + passwd
								+ "&action=submit&response_type=code&isLoginSina=0&redirect_uri=" + redirectURI
								+ "&userId=" + userId + "&client_id=" + clientId);
				loginPost.setHeader("Host", "login.sina.com.cn");
				loginPost.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0");

				response = client.execute(loginPost);

				if (response != null) {

					entity = response.getEntity();
					String loginSuccess = EntityUtils.toString(entity);
					obj = JSON.parseObject(loginSuccess);
					return obj;
				}

			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return null;
	}
然后获取verifyToken。

/**
	 * 获取授权的token
	 * 
	 * @param loginObj
	 * @return
	 */
	public static String getVerifyToken(JSONObject loginObj) {
		// 授權登陸
		HttpPost postMethod = new HttpPost(url);
		List<NameValuePair> nvps = new ArrayList<>();
		// 应用的App Key
		nvps.add(new BasicNameValuePair("client_id", clientId));
		// 应用的重定向页面
		nvps.add(new BasicNameValuePair("redirect_uri", redirectURI));
		// 模拟登录参数
		// 开发者或测试账号的用户名和密码
		nvps.add(new BasicNameValuePair("display", "default"));
		// 猜測是登陸的權證
		nvps.add(new BasicNameValuePair("ticket", loginObj.getString("ticket")));
		// nvps.add(new BasicNameValuePair("uid",
		// obj.getString("uid")));
		nvps.add(new BasicNameValuePair("regCallback", url + "?client_id=" + clientId
				+ "&response_type=code&display=default&redirect_uri=" + redirectURI + "&from=&with_cookie="));
		nvps.add(new BasicNameValuePair("isLoginSina", "0"));
		nvps.add(new BasicNameValuePair("action", "login"));
		nvps.add(new BasicNameValuePair("withOfficalFlag", "0"));
		nvps.add(new BasicNameValuePair("appkey62", appkey));
		postMethod.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
		// 添加头信息
		postMethod.setHeader("Referer", url);
		postMethod.setHeader("Host", "api.weibo.com");
		postMethod.setHeader("Origin", "https://api.weibo.com");
		postMethod.setHeader("Content-Type", "application/x-www-form-urlencoded");
		postMethod.setHeader("Upgrade-Insecure-Requests", "1");
		postMethod.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1;rv:11.0) Gecko/20100101 Firefox/11.0");

		// client = HttpClients.createDefault();
		response = null;
		try {
			response = client.execute(postMethod);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		if (response != null) {
			entity = response.getEntity();
			String verifyToken = null;
			try {
				String loginHtml = EntityUtils.toString(entity);
				int index = loginHtml.indexOf("verifyToken") + 20;
				String tmp = loginHtml.substring(index, loginHtml.length());
				index = tmp.indexOf("/>");
				tmp = tmp.substring(0, index - 1);
				verifyToken = tmp;
				return verifyToken;
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return null;
	}
最后我们就可以获取到获取token的code了

/**
	 *  获取授权code
	 * @param loginObj
	 * @param verifyToken
	 * @return
	 */
	public static String getCode(JSONObject loginObj, String verifyToken) {
		// 正式授權
		HttpPost postMethod = new HttpPost(url);
		List<NameValuePair> nvps = new ArrayList<>();
		nvps = new
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值