无法使用 java 从 yahoo API 获取 OAuth 2.0 访问令牌
Cannot get OAuth2.0 accessToken from yahooAPI using java
我正在使用他们的开发人员指南实施 yahoo Oauth 2.0 java https://developer.yahoo.com/oauth2/guide/。
在第四步,它说要交换访问令牌的授权代码,我得到了类似 "invalid request" 的响应。
在指南中,他们提到将 consumerKey 和 consumerSecret 以 base64 编码格式作为响应包含在内header。
我也包含了它,但我不确定这是否会导致无效响应。
我错过了一些可以帮助我解决这个问题的地方。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/helloWorld")
public class helloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
private static String gUri ="";
private static String contactsUri="";
private static String yahooServer="";
private static String consumer_key = "foo";
private static String redirect_uri = "https://foo/TestServlet/helloWorld?a=process";
private static String consumer_secret = "foo";
private static String encodedValue="";
public helloWorld() {
super();
}
public void init(ServletConfig config) throws ServletException
{
super.init(config);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
String action = request.getParameter("a");
try {
if (action.equals("init")) {
String url = "https://api.login.yahoo.com/oauth2/request_auth?client_id="
+ consumer_key
+ "&redirect_uri="
+ redirect_uri
+ "&response_type=code&language=en-us";
pw.println(url);
response.sendRedirect(url);
} else if (action.equalsIgnoreCase("process")) {
String code = request.getParameter("code");
System.out.println("code::::" + code);
System.out.println("helloWorld:doPost:requesturl:" + request.getQueryString());
doPost(request, response);
}else if(action.equalsIgnoreCase("getAccessToken")){
System.out.println("helloWorld:doGet:accessToken" +request.getAttribute("access_token") );
System.out.println("helloWorld:doGet:accessToken" +request.getParameter("access_token") );
}
else{
System.out.println("helloWorld:doGet:else" );
}
}finally {
pw.close();
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String code = request.getParameter("code");
redirect_uri="https://foo/TestServlet/helloWorld?a=getAccessToken";
String getAccessToken="https://api.login.yahoo.com/oauth2/get_token?client_id="
+consumer_key
+"&client_secret="
+consumer_secret
+"&redirect_uri="
+redirect_uri
+"&code="
+code
+"&grant_type=access_token";
encodedValue=encoder.encode(consumer_key+":"+consumer_secret);
System.out.println("helloWorld:doPost:encodedVAlue-->" +encodedValue );
response.setHeader("Authorization:","Basic"+encodedValue);
response.setHeader("Content-Type:","application/x-www-form-urlencoded");
System.out.println("helloWorld:doGet:contactsUri" +getAccessToken );
response.sendRedirect(getAccessToken);
}
}
您需要 POST 将参数作为 form-encoded HTTP POST 请求中的参数发送到令牌端点 (oauth2/get_token
),而不是将它们作为查询参数提供重定向到令牌端点。您可以使用 Sending HTTP POST Request In Java
中的代码
此外,请注意:
- 你需要
Basic
和 encodedValue
之间的 space
setHeader
方法将:
添加到Header本身,你不需要在第一个参数中提供它
但是 1. 和 2. 与实际解决方案代码无关,因为您不应该在对调用者的 HTTP 响应上设置 Header,而是在对 Yahoo 的 HTTP 请求上设置。
我正在使用他们的开发人员指南实施 yahoo Oauth 2.0 java https://developer.yahoo.com/oauth2/guide/。
在第四步,它说要交换访问令牌的授权代码,我得到了类似 "invalid request" 的响应。
在指南中,他们提到将 consumerKey 和 consumerSecret 以 base64 编码格式作为响应包含在内header。
我也包含了它,但我不确定这是否会导致无效响应。
我错过了一些可以帮助我解决这个问题的地方。
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/helloWorld")
public class helloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
private static String gUri ="";
private static String contactsUri="";
private static String yahooServer="";
private static String consumer_key = "foo";
private static String redirect_uri = "https://foo/TestServlet/helloWorld?a=process";
private static String consumer_secret = "foo";
private static String encodedValue="";
public helloWorld() {
super();
}
public void init(ServletConfig config) throws ServletException
{
super.init(config);
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
String action = request.getParameter("a");
try {
if (action.equals("init")) {
String url = "https://api.login.yahoo.com/oauth2/request_auth?client_id="
+ consumer_key
+ "&redirect_uri="
+ redirect_uri
+ "&response_type=code&language=en-us";
pw.println(url);
response.sendRedirect(url);
} else if (action.equalsIgnoreCase("process")) {
String code = request.getParameter("code");
System.out.println("code::::" + code);
System.out.println("helloWorld:doPost:requesturl:" + request.getQueryString());
doPost(request, response);
}else if(action.equalsIgnoreCase("getAccessToken")){
System.out.println("helloWorld:doGet:accessToken" +request.getAttribute("access_token") );
System.out.println("helloWorld:doGet:accessToken" +request.getParameter("access_token") );
}
else{
System.out.println("helloWorld:doGet:else" );
}
}finally {
pw.close();
}
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String code = request.getParameter("code");
redirect_uri="https://foo/TestServlet/helloWorld?a=getAccessToken";
String getAccessToken="https://api.login.yahoo.com/oauth2/get_token?client_id="
+consumer_key
+"&client_secret="
+consumer_secret
+"&redirect_uri="
+redirect_uri
+"&code="
+code
+"&grant_type=access_token";
encodedValue=encoder.encode(consumer_key+":"+consumer_secret);
System.out.println("helloWorld:doPost:encodedVAlue-->" +encodedValue );
response.setHeader("Authorization:","Basic"+encodedValue);
response.setHeader("Content-Type:","application/x-www-form-urlencoded");
System.out.println("helloWorld:doGet:contactsUri" +getAccessToken );
response.sendRedirect(getAccessToken);
}
}
您需要 POST 将参数作为 form-encoded HTTP POST 请求中的参数发送到令牌端点 (oauth2/get_token
),而不是将它们作为查询参数提供重定向到令牌端点。您可以使用 Sending HTTP POST Request In Java
此外,请注意:
- 你需要
Basic
和encodedValue
之间的 space
setHeader
方法将:
添加到Header本身,你不需要在第一个参数中提供它
但是 1. 和 2. 与实际解决方案代码无关,因为您不应该在对调用者的 HTTP 响应上设置 Header,而是在对 Yahoo 的 HTTP 请求上设置。