3

ここに示す「Web サーバー アプリケーション」の例を使用しています。コールバック サーブレットでアクセス トークンを取得したいのですが、うまく取得できません。以下は私のコードです

  @Override
  protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
    // return user ID
      Iterator<String> iterator = req.getParameterMap().keySet().iterator();
        while (iterator.hasNext()) {
            String string = iterator.next();

            System.out.println(string+"---++--"+req.getParameter(string));
        }
        GoogleAuthorizationCodeTokenRequest newTokenRequest = new GoogleAuthorizationCodeFlow.Builder(new NetHttpTransport(), new JacksonFactory(),
                                                             "2XXXXXX7218.apps.googleusercontent.com", "KugD_XXX_7vqnGZVXXXXX1M",
                                                              Collections.singleton("https://gdata.youtube.com"))
                                                              .build().newTokenRequest(req.getParameter("code"));
        //GoogleAuth
        GoogleTokenResponse token = newTokenRequest.setRedirectUri("/").execute();
        String accessToken = token.getAccessToken();
        System.out.println("accesstoken:"+accessToken);
        return "";
  }

このコードを実行した後、次のエラーが発生します

com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
  "error" : "invalid_request"
}

一言で言えば、「コード」パラメーター(リクエストコード)を取得していますが、それをアクセストークンに変換する方法がわかりません。私はすでにGoogle APIを見てき ました-Oauth2からのトークンのリクエストは「invalid_request」を返し ます

編集

Google API がうまくいかなかったので、ライブラリを使用せずに次のコードを書きました

 URL url = new URL("https://accounts.google.com/o/oauth2/token");
    connection = (HttpURLConnection) url.openConnection();
    String urlParameters = "code=" + req.getParameter("code") + "&client_id=29852.apps.googleusercontent.com&client_secret=KugD_LVi_7vqnssssxxxNRBz1M"+
            "&redirect_uri=https://flixomnia.com/oauth2callback&grant_type=authorization_code&scope=https://gdata.youtube.com&response_type=token";
    connection.setDoOutput(true);
    connection.setDoInput(true);
    connection.setInstanceFollowRedirects(true);
    connection.setRequestMethod("POST");
    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    connection.setRequestProperty("Authorization", "Bearer 4/q3Xh_pJI458XXXXXXXkh-lxe3-8.cmaD6o7V5BkQXE-XXXXX-edgI");
    connection.setRequestProperty("Content-Length", "" + Integer.toString(urlParameters.getBytes().length));
    connection.setRequestProperty("X-GData-Key", "key=AI39siXXXXXXM7tyHBvXEM1lLcORetit6QSArQ3sjelBxXXXXXXtgLSPdZPxvsF_vkntOQMnAEYAuVFqhN7oUw");
    connection.setRequestProperty("GData-Version", "2");

    connection.setUseCaches(false);
    //com.google.gdata.client.youtube.YouTubeService service = new com.google.gdata.client.youtube.YouTubeService("","");
    //YouTubeMediaGroup g = new YouTubeMediaGroup();


    DataOutputStream wr = new DataOutputStream(connection.getOutputStream());

    wr.writeBytes(urlParameters);
    wr.flush();
    InputStream inputStream = connection.getInputStream();
    byte[] b = new byte[1024];
    while (inputStream.read(b) != -1) {
        System.out.print(new String(b));

    }
    System.out.println("");
    wr.close();
    connection.disconnect();

しかし、それでも次のエラーが発生します

    {  "error" : "invalid_request"}
java.io.IOException: Server returned HTTP response code: 400 for URL: https://accounts.google.com/o/oauth2/token
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1615)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
    at com.broadcastr.servlets.YouTubeCallbackService.getUserId(YouTubeCallbackService.java:168)
    at com.google.api.client.extensions.servlet.auth.oauth2.AbstractAuthorizationCodeCallbackServlet.doGet(AbstractAuthorizationCodeCallbackServlet.java:130)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1001)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722)
4

5 に答える 5

5
  1. setRedirectUri上記の初期コードのアクセストークンを取得する方法では、がredirect_uri正しく設定されていません。redirect_uriクライアント登録時に指定したものを使用してください。

  2. EDITコードでは、必要なパラメーターをアクセストークンのエンドポイントに送信しているときに、サポートされていないパラメーターresponse_typeも要求とともに送信されます。パラメータを削除response_typeすると、目的が解決するはずです。

    また、OAuth2 RFCドラフトinvalid_requestによると、リクエストがクライアントを認証するために複数のメカニズムを利用している場合、アクセストークンエンドポイントもエラーになる可能性があります。したがって、Authorizationヘッダーを削除するとURLConnection、目的も解決するはずです。

于 2012-12-11T22:19:22.310 に答える
2

また、この問題を解決するために2日間無駄にしました。を使用してトークン リクエストを送信できませんでしたHttpUrlConnectionHttpClient私のために働いた。

以下は作業コードです:

1) 渡された値:

String url = "https://accounts.google.com/o/oauth2/token";
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("grant_type", "authorization_code"));

nameValuePairs.add(new BasicNameValuePair("client_id",client_id));
nameValuePairs.add(new BasicNameValuePair("client_secret", client_secret));
nameValuePairs.add(new BasicNameValuePair("redirect_uri", "http://example.com/bin/showcase/servlet/googlecallback"));
nameValuePairs.add(new BasicNameValuePair("code", code));

StringBuffer postResult =  sendPost(url, nameValuePairs);

2) 方法

private StringBuffer sendPost(String url, List<NameValuePair> postParams) 
        throws Exception {

    HttpPost post = new HttpPost(url);
    HttpClient client = new DefaultHttpClient();

    // add header
    post.setHeader("Host", "accounts.google.com");
    post.setHeader("Accept", 
            "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
    post.setHeader("Accept-Language", "en-US,en;q=0.5");
    post.setHeader("Connection", "keep-alive");
    post.setHeader("Referer", "https://accounts.google.com/o/oauth2/token");
    post.setHeader("Content-Type", "application/x-www-form-urlencoded");

    post.setEntity(new UrlEncodedFormEntity(postParams));

    HttpResponse response = client.execute(post);

    int responseCode = response.getStatusLine().getStatusCode();

    BufferedReader rd = new BufferedReader(
            new InputStreamReader(response.getEntity().getContent()));

    StringBuffer result = new StringBuffer();
    String line = "";`enter code here`
    while ((line = rd.readLine()) != null) {
        result.append(line);
    }
    return result;
}
于 2013-10-09T06:33:03.360 に答える
0

上記の Richard の言うとおりです。setRedirectUri では、アプリケーションを登録したときに指定した完全なリダイレクト URI を使用する必要があります。それは相対的なものではなく、絶対的なものであるべきです。(そしてできればhttps)

ダブ

于 2012-11-30T23:44:07.010 に答える
0

リクエスト URL から EDIT コードの問題である「&response_type=token」パラメータを削除してください。これで問題が解決します。

于 2013-08-07T14:04:08.337 に答える
0

私の Oauth サーバーにアクセスする Java アプリと Android アプリを取得する際に、次の 2 つのライブラリが役立つことがわかりました。

  1. google-oauth-java-client DailyMotion で使用されます。 https://code.google.com/p/google-oauth-java-client/http://samples.google-oauth-java-client.googlecode.com/hg/dailymotion-cmdline-sample/instructions.html このライブラリ/サンプル コードを使用すると、Java から独自の OAuth2 サーバーにアクセスできます。

  2. google-api-java-client で使用: Android (Latitude) の Auth2 フローhttp://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/ このライブラリ/サンプル コードは具体的にはOAuth2 を介して Google API にアクセスするため。

どの問題を解決しようとしているのかわかりませんが、これら 2 つのうちの 1 つが役立つはずです。どちらも「コード」を「authToken」に交換するプロセスを経ますが、方法が少し異なります。RB

于 2012-12-11T02:19:48.647 に答える