最近处理用户授权问题,找了很多文档 写的都很乱 很杂,官方文档也是如此 下面整理一下内容
1.接收前端授权的code获取token
一切的前提是你有开发者账号并且获取了相关的权限不然就白瞎 回调地址在开发者账号里面设置
/**
* 通过授权code获取token
* @param consumerKey clientId 开发者账号里面的
* @param consumerSecret clientSecret 开发者账号里面的
* @param code code码
* @param callbackUrl 回调地址
* @param active 当前环境 dev test prod
* @return
*/
public static String getBearerToken(String consumerKey, String consumerSecret, String code,String callbackUrl,String active) {
String credentials = Credentials.basic(consumerKey, consumerSecret);
System.out.println(credentials);
RequestBody requestBody = new FormBody.Builder()
.add("grant_type", "authorization_code")
.add("code", code)
.add("redirect_uri",callbackUrl)
.add("client_id",consumerKey)
.add("code_verifier","challenge")
.build();
Request request = new Request.Builder()
.url("https://api.twitter.com/2/oauth2/token")
.header("Authorization", credentials)
.header("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8")
.post(requestBody)
.build();
OkHttpClient client = getClient(active);
try (Response response = client.newCall(request).execute()) {
String responseString = response.body().string();
if (response.isSuccessful()) {
return responseString;
} else {
throw new IOException("Unexpected response code " + response.code() + ": " + responseString);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
private static OkHttpClient getClient(String active){
OkHttpClient client =null;
if (null==active ||"dev".equals(active)){
OkHttpClient.Builder builder = new OkHttpClient.Builder();
//设置代理,需要替换(测试时需要用到--api域名被墙) TODO:生产环境去掉
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 7890));
builder.proxy(proxy);
client = builder
.build();
}
if ("prod".equals(active)||"test".equals(active)){
client = new OkHttpClient();
}
return client;
}
如果code有问题就会报 {“errors”:[{“code”:44,“message”:“authorization_code parameter is invalid”,“label”:“invalid_parameter”}]}
没问题就正常解析
**有问题可能是API Key 是 OAuth 2.0 客户端凭据中的客户端标识符,而 client_id 是 OAuth 2.0 授权流程中的客户端标识符。在 Twitter API 的文档和代码示例中,API Key 和 client_id 可能会互换使用,指的是同一个值。
apikey和clientid混淆了 或者是code过期了 或者code已经获取过token了
一定要注意 30S code过期
这里踩了很大的坑 ,部分用户可能通过代码不行 可以尝试这种方式 通过cmd
// 设置代理地址和端口号
String proxyHost = "127.0.0.1";
int proxyPort = 7890;
// 构造命令行命令
String[] command = {
"curl",
"-x", proxyHost + ":" + proxyPort,
"--location",
"--request", "POST",
"https://api.twitter.com/2/oauth2/token",
"--header", "Content-Type: application/x-www-form-urlencoded",
"--header", "Authorization: Basic 自己的",
"--data-urlencode", "code="+code,
"--data-urlencode", "grant_type=authorization_code",
"--data-urlencode", "client_id= 自己的",
"--data-urlencode", "redirect_uri= 自己的回调",
"--data-urlencode", "code_verifier=challenge"
};
// 执行命令行命令
Process process = null;
try {
process = Runtime.getRuntime().exec(command);
// 读取命令行输出
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
return line;
} catch (IOException e) {
System.out.println(e.getMessage());
return null;
}
2.通过token获取用户信息
public static Map<String,String> getUserInfo(String bearerToken,String active){
String userInfoUrl = "https://api.twitter.com/2/users/me";
OkHttpClient client = getClient(active);
Request request = new Request.Builder()
.url(userInfoUrl)
.method("GET", null)
.addHeader("Authorization", "Bearer " + bearerToken)
.addHeader("User-Agent", "v2UserLookupJava")
.build();
try {
Response response = client.newCall(request).execute();
if (response.isSuccessful()) {
ResponseBody responseBody = response.body();
if (responseBody != null) {
String string = responseBody.string();
Map<String, String> map = getTwitterUser(string);
return map;
}
} else {
System.out.println("HTTP error code: " + response.code());
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 解析获取用户信息json
* @param jsonStr
* @return
*/
private static Map<String,String> getTwitterUser(String jsonStr){
JSONObject jsonObj = new JSONObject(jsonStr);
JSONObject dataObj = jsonObj.getJSONObject("data");
String id = dataObj.getStr("id");
String name = dataObj.getStr("name");
Map<String, String> map = new HashMap<>();
map.put("id",id);
map.put("name",name);
return map;
}
返回的数据格式 {“data”:{“id”:“xxxxx”,“name”:“xxxxx”,“username”:“xxxx”}}
到这里就完成啦