2

我正在尝试检索访问令牌。我已经设法让用户授权我的应用程序,现在我正在尝试检索访问令牌。这是 reddit oauth2 文档:https ://github.com/reddit-archive/reddit/wiki/oauth2 这是我正在使用的 HTTPoison 发布请求:https ://hexdocs.pm/httpoison/HTTPoison.html#post /4

我不知道如何发出 post 请求,client_id 应该在正文还是在标题等处。

  def get_oauth_token(token, state) do
    # TODO: compare state with old state to prevent malicious users
    cfg = config()

    url = 'https://www.reddit.com/api/v1/access_token'
    body  = %{
      grant_type: "authorization_code",
      code: token,
      redirect_uri: cfg[:redirect_uri],
      client_id: cfg[:client_id],
      client_secret: cfg[:client_secret]
    }
    |> Jason.encode()
    |> ok()

    HTTPoison.post(url, body, [
      {"Accept", "application/json"},
      {"Content-Type", "application/x-www-form-urlencoded"},
    ])
  end

  defp ok({:ok, response}), do: response

我收到状态码 401

预期结果

{
    "access_token": Your access token,
    "token_type": "bearer",
    "expires_in": Unix Epoch Seconds,
    "scope": A scope string,
    "refresh_token": Your refresh token
}
4

1 回答 1

2

API 是期待的application/x-www-form-urlencoded,所以你不应该编码成 JSON。

根据Reddit 文档,您还需要使用 HTTP Basic 身份验证将您的client_id和编码client_secret到标头中。Authorization

url = "https://www.reddit.com/api/v1/access_token"

headers = [
  {"Content-Type", "application/x-www-form-urlencoded"},
  {"Authorization", "Basic " <> Base.encode64("#{cfg.client_id}:#{cfg.client_secret}")}
]

data = [
  grant_type: "authorization_code",
  code: token,
  redirect_uri: cfg.redirect_uri
]

HTTPoison.post(url, {:form, data}, headers)

查看文档以了解发布表单 url 编码HTTPoison.Request{:form, data}语法。

于 2019-07-20T15:41:11.830 回答