在上一篇内容已经介绍了怎么申请twitter开放的API接口。
下面介绍怎么通过twitter提供的API,进行授权登录功能。
开发者页面设置
首先在开发者页面开启“用户认证设置”,点击edit进行信息编辑。
我的授权登录是个网页,并且只需要进行简单的登录和获取登录人员基础信息这些信息,所以进行了以下设置。
这里一定要配置回调地址,这个地址至关重要。
测试期间不需要域名这些,也不需要天公网IP。
内网本地地址就可以,http://localhost:63342/index.html 也可以(自己可以写一个简单的测试页)
了解授权步骤
编写代码之前我们要先了解twitter授权登录的三步骤。
https://developer.twitter.com/en/docs/authentication/guides/log-in-with-twitter
以上链接有详细的授权验证过程,当然我也可以简单介绍一下。
- 请求https://api.twitter.com/oauth/request_token接口。 在请求这个接口的时候,不仅要传申请的consumerKey和consumerSecret,还得填写oauth_callback的值。这个值的内容填写你上面在Callback URL里填写的回调地址【http://localhost:63342/index.html】。
- 请求成功后拿到oauth_token值,网页调转到https://api.twitter.com/oauth/authenticate页面,链接后面加上 ** ?oauth_token= ** 的值。
参数成功的话,会正确调转到twitter授权的页面,点击授权按钮后,twitter页面会跳转回你填写的页面链接。
回到自己的页面后,页面的URL会携带两个参数和参数值。oauth_token和oauth_verifier
- 拿到URL中传回的这两个值,请求https://api.twitter.com/oauth/access_token接口,拿到用户授权的screen_name和user_id,auth_token和oauth_token_secret这些值。
- token和token_secret两个参数,可以通过请求https://api.twitter.com/2/users/me接口获取用户的一些基础信息。
注意!以上过程,oauth_token和oauth_verifier的值失效时间很短暂,找到一个帖子说只有30秒,所以接口连贯性请求很重要,只有速度,快速授权过程才能完成。
编写代码
流程介绍完,开始编写代码。
- 首先,网页上增加一个按钮。
<!-- 点击按钮触发授权 -->
<button onclick="authorizeTwitter()">Twitter授权登录</button>
编写js代码,authorizeTwitter()方法
function authorizeTwitter() {
// 发起授权请求
$.ajax({
url:'http://localhost:8070/twitter/login',
type:'POST',
async: true,
cache: false,
contentType: false, //不设置内容类型
processData: false, //不处理数据
success:function(data){
var code = data.code;
if(code == 200){
window.location.href ="https://api.twitter.com/oauth/authenticate?oauth_token="+data.result;
}else{
console.error('授权请求错误:');
layer.alert("请求失败,请稍候重试");
}
}
});
}
- twitter/login接口核心代码如下
callback的传值就是开发者里配置的Callback URL的填写的值。
和网页配置的保持一致,不可随意传值。
active的值只是用于开启代理的开关,上篇代码有写,根据自己需求传不同的值。
/**
* 第一步:通过授权code获取token
* @param active 当前环境 dev test prod
* @return
*/
public static String RequestToken(String callback,String active) {
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
// 创建HttpParameters对象,并添加自定义参数
HttpParameters parameters = new HttpParameters();
parameters.put(OAuth.OAUTH_CALLBACK, callback);
consumer.setAdditionalParameters(parameters);
// 创建HttpClient对象
HttpClient httpClient = setProxy(active);
// 创建API请求,例如获取用户的时间线
String apiUrl = "https://api.twitter.com/oauth/request_token";
HttpGet request = new HttpGet(apiUrl);
// 对请求进行OAuth1签名
try {
consumer.sign(request);
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
}
// 发起API请求
HttpResponse response = null;
try {
response = httpClient.execute(request);
} catch (IOException e) {
e.printStackTrace();
}
// 处理API响应
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = null;
try {
responseBody = EntityUtils.toString(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
if (statusCode == 200) {
System.out.println("API调用成功!");
System.out.println("响应内容:");
System.out.println(responseBody);
return responseBody;
} else {
System.out.println("API调用失败,状态码:" + statusCode);
System.out.println("错误信息:");
System.out.println(responseBody);
return responseBody;
}
}
成功返回的值形式如下:
oauth_token=qQn3YwAAAAABq1bmAAABi9gPG1M&oauth_token_secret=2QBmMyDV450YG1dtdf5KnnGrztnRXKmR&oauth_callback_confirmed=true
我用httpcore工具进行解析,需要用到的类如下。
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
List<NameValuePair> parameters = URLEncodedUtils.parse(responseString, StandardCharsets.UTF_8);
// 遍历参数并输出键值对
for (NameValuePair parameter : parameters) {
String key = parameter.getName();
String value = parameter.getValue();
map.put(key,value);
}
把oauth_token值传到前台页面,前台页面进行跳转。
参考如下:
https://api.twitter.com/oauth/authenticate?oauth_token=qQn3YwAAAAABq1bmAAABi9gPG1M
授权成功之后,调转回调页面。如果之前授权过,会很快跳转到回调页面。
http://localhost:63342/index.html?oauth_token=s19K7gAAAAABq1bmAAABi9fpDPI&oauth_verifier=cHqqlM9vi0gn8EDDtrCmUvh3jCSQCGcL
拿到oauth_token和oauth_verifier的值,页面load()方法解析获取oauth_token和oauth_verifier请求第二个接口。
function callbackTwitter(token,verifier) {
var authorize = new FormData();
authorize.append("oauth_token",token);
authorize.append("oauth_verifier",verifier);
console.log(authorize);
// 发起授权请求
$.ajax({
url:'http://localhost:8070/twitter/verifier',
type:'POST',
data:authorize,
async: true,
cache: false,
contentType: false, //不设置内容类型
processData: false, //不处理数据
success:function(data){
// var data = eval('(' + data + ')');
var code = data.code;
if(code == 200){
//自己业务
}else{
console.error('授权请求错误:');
layer.alert("请求失败,请稍候重试");
}
}
});
}
第二个接口核心Java代码。
oauth_verifier值是放在请求体里,和第一个接口oauth_callback参数方式有些不同。
/**
* 第二部,页面跳转
* @param token
* @param verifier
* @param active
* @return
*/
public static String callback(String token,String verifier, String active) {
// 创建CommonsHttpOAuthConsumer对象,设置OAuth1验证参数
CommonsHttpOAuthConsumer consumer = new CommonsHttpOAuthConsumer(consumerKey, consumerSecret);
// 创建HttpParameters对象,并添加自定义参数
HttpParameters parameters = new HttpParameters();
parameters.put(OAuth.OAUTH_TOKEN, token);
consumer.setAdditionalParameters(parameters);
// 创建HttpClient对象
HttpClient httpClient = setProxy(active);
// 创建API请求,例如获取用户的时间线
String apiUrl = "https://api.twitter.com/oauth/access_token";
HttpPost request = new HttpPost(apiUrl);
try {
request.setHeader("Content-Type","application/x-www-form-urlencoded");
consumer.sign(request);
// 创建参数列表
List<NameValuePair> bodypara = new ArrayList<>();
bodypara.add(new BasicNameValuePair("oauth_verifier", verifier));
// 将参数转换为UrlEncodedFormEntity
StringEntity entity = new UrlEncodedFormEntity(bodypara, StandardCharsets.UTF_8);
// 设置HttpPost的实体
request.setEntity(entity);
// request.setEntity();
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
}
// 发起API请求
HttpResponse response = null;
try {
response = httpClient.execute(request);
} catch (IOException e) {
e.printStackTrace();
}
// 处理API响应
int statusCode = response.getStatusLine().getStatusCode();
String responseBody = null;
try {
responseBody = EntityUtils.toString(response.getEntity());
} catch (IOException e) {
e.printStackTrace();
}
if (statusCode == 200) {
System.out.println("API调用成功!");
System.out.println(responseBody);
return responseBody;
} else {
System.out.println("API调用失败,状态码:" + statusCode);
return responseBody;
}
}
请求成功后的返回内容。
oauth_token=1517001992861716480-xVY7MpIqQrH1XeFv5l6rOL0FqG9WPj&oauth_token_secret=A52yWlrFd1MDIrYU0IcnmlnmimMOw0UXRJNfnry3bJNfm&user_id=151700199286171xxxx&screen_name=TTTTTTTXX
这用户的重要的用户ID和用户名就获取到了。
整个授权流程算是完成了。
我的业务是需要获取用户的粉丝数和其他一些基础信息,这时候就可以用返回的oauth_token和oauth_token_secret两个值请求https://api.twitter.com/2/users/me接口。
代码示例可在上篇看到。