最近需要使用微博开放平台的一些功能,由于官方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