【问题标题】:Play framework, Setting HTTP POST request headers播放框架,设置 HTTP POST 请求标头
【发布时间】:2014-12-07 06:52:58
【问题描述】:

问题

将 Google Plus Sign In Api 与 Play 框架一起使用时,您是否必须以不同的方式设置标头?我在这里做错了什么吗?

背景

我正在使用 Play Framework(在 Java 中)来使用 Google Plus Sign in Api。
我在 OAuth 身份验证的第二阶段遇到了问题,将 Authorization Code 交换为 Token。

基本 OAuth 流程

Pretty Picture

  1. 将用户重定向到User login/Consent screen
    • 这会询问用户是否要授予您对所请求范围的应用程序权限
    • 网址:https://accounts.google.com/o/oauth2/auth
  2. 将Authorization Code 换成Token
    • 如果用户授予您的应用程序权限,那么他们将被重定向到您指定的 URL,其中该 URL(作为 GET 参数)将是 Authorization Code。
    • 然后您的应用程序可以使用此Authoriztion Code 从服务器获取Token
    • 您的应用程序通过向 Google 服务器(或您正在使用的任何服务)上的端点发出 HTTP 请求来执行此操作
      • 网址:https://accounts.google.com/o/oauth2/token
  3. 在 API 请求中使用 Token

问题

要将Authorization Code 换成Token,使用Google Plus Sign In Api,您必须向https://accounts.google.com/o/oauth2/token 发出POST 请求,并具有以下边界

{
  "code": "Security Code Returned from Step 1",
  "client_id": "Client Id that was given to you in GApi Console",
  "client_secret": "Client Secret that was given to you in the GApi Console",
  "redirect_uri": "Redirect Uri you specified in the GApi Console",
  "grant_type": "authorization_code"
}

但是,当我使用所有正确的参数发出这个请求时,我得到了这个错误

{
  "error" : "invalid_request",
  "error_description" : "Required parameter is missing: grant_type"
}

来自 Google Plus 登录 API

要在 Play Framework 中发出 HTTP 请求,请使用 WS Library。我提出这样的要求

public static F.Promise<Result> OAuthCallback(String state, String code){
  /*
    Note:
      - The GoogleStrategy class is just a class that holds all my GApi credentials
      - The parameters (String state, String code) are just GET params from Step 1, returned by the GApi
  */

  //Make URL builder
  WSRequestHolder requestHolder = WS.url(GoogleStrategy.getTokenUrl);

  //Set headers
  requestHolder.setHeader("code", code);
  requestHolder.setHeader("client_id", GoogleStrategy.clientId);
  requestHolder.setHeader("client_secret", GoogleStrategy.clientSecret);
  requestHolder.setHeader("redirect_uri", GoogleStrategy.redirectUri);
  requestHolder.setHeader("grant_type", GoogleStrategy.grantType);//GoogleStrategy.grantType = "authorization_code"

  //Make HTTP request and tell program what to do once the HTTP request is finished
  F.Promise<Result> getTokenPromise = requestHolder.post("").map(
    new F.Function<WSResponse, Result>() {
      public Result apply(WSResponse response){
        return ok(response.asJson());//Returning result for debugging
      }
    }
  );

  return getTokenPromise;//Return promise, Play Framework will handle the Asynchronous stuff
}

如你所见,我设置了标题grant_type。为了确保设置标头正常工作,我制作了一个程序,在 NodeJS(Source) 中吐出请求的标头,这就是结果

{
  "HEADERS": {
    "host": "127.0.0.1:3000",
    "code": "4/qazYoReIJZAYO9izlTjjJA.gihwUJ6zgoERgtL038sCVnsvSfAJkgI",
    "grant_type": "authorization_code",
    "client_secret": "XXXX-CENSORED FOR SECURITY PURPOSES-XXX",
    "redirect_uri": "http://127.0.0.1:9000/api/users/auth/google/callback",
    "client_id": "XXXX-CENSORED FOR SECURITY PURPOSES-XXX",
    "content-type": "text/plain; charset=utf-8",
    "connection": "keep-alive",
    "accept": "*/*",
    "user-agent": "NING/1.0",
    "content-length": "14"
  }
}

【问题讨论】:

  • 你应该用你得到的错误更新你的答案。
  • 您已经在我的回答中的评论中发布了该信息(您的代码)。我要的是你得到的错误(即你从谷歌得到的 HTTP 代码和正文)。
  • @Salem Oops Edited(那是我的愚蠢:P)
  • 查看我的编辑。您也可以尝试在 redirect_uri 值中使用url encoding。

标签: java web-services oauth playframework google-api


【解决方案1】:

我认为这些不是作为标题发送,而是作为正文发送。在您提供的链接中有一个示例:

POST /o/oauth2/token HTTP/1.1
Host: accounts.google.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=8819981768.apps.googleusercontent.com&
client_secret={client_secret}&
redirect_uri=https://oauth2-login-demo.appspot.com/code&
grant_type=authorization_code

所以将它们传递给您的post 电话:

StringBuilder sb = new StringBuilder();
sb.append("code=").append(code)
    .append("&client_id=").append(GoogleStrategy.clientId)
    .append("&client_secret=").append( GoogleStrategy.clientSecret)
    .append("&redirect_uri=").append(GoogleStrategy.redirectUri)
    .append("&grant_type=").append(GoogleStrategy.grantType)

requestHolder.setContentType("application/x-www-form-urlencoded")
    .post(sb.toString());

【讨论】:

  • 使用this code(实施您的建议)我仍然从 Google Plus Login Api 收到同样的错误。
猜你喜欢
  • 1970-01-01
  • 2016-10-15
  • 1970-01-01
  • 2016-11-13
  • 2017-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多