使用Rails中的资源所有者密码凭据进行身份验证

时间:2017-03-16 19:00:31

标签: ruby-on-rails oauth oauth-2.0

我对OAuth身份验证方案很陌生。目前给我带来问题的是在Rails应用程序中从服务器获取access_token。

到目前为止,我读过几篇关于OAuth 2.0中与资源所有者密码凭证相关的方法的文章,但它仍然让我无处可去。 仅举几个Official documentation regarding ROPC / Introduction to OAuth2 / Description of OAuth2 gem from Intridea

我要连接的服务器允许密码授予。它是由第三方部署的,所以我认为一切都很好。在手册页上,他们定义了授权示例,如下所示:

curl -X POST -d
'grant_type=password&username=USER_EMAIL&password=YOUR_PASSWORD&client_id=CLIENT_ID&client_secret=CLIENT_SECRET'
'https://auth.example.com/oauth2/token'

我拥有上面提到的所有数据。 BTW,client_id和client_secret是文档中包含的通用值。服务器使用Doorkeeper gem来实现OAuth2。

要从服务器检索access_token,我只需将Doorkeeper的wiki代码建议放入我的一个控制器中。 Testing ROPC for Doorkeeper

我在使用来自Intridea的OAuth2 gem的Rails API应用程序中的代码:

 def test
    client = OAuth2::Client.new(CLIENT_ID, CLIENT_SECRET,
     site: 'https://auth.example.com/oauth2/token')

    access_token = client.password.get_token(username, password)
    Rails.logger.info access_token.token
  end

访问localhost / test后得到的结果是OAuth2已完成500内部服务器错误::错误说我查找的页面不存在。

当尝试从命令行使用curl和各自的数据时,我收到:

WWW-Authenticate: Bearer realm="Doorkeeper", error="invalid_grant", error_description="The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."

请在这些设置中告知可能导致问题的原因。

1 个答案:

答案 0 :(得分:1)

由于我似乎忽略了一件重要的事情,我们应该明确声明与token_url地址相关的site,而不是将site参数视为整个路径。

因此,为了请求access_token,我的方法应如下所示:

def test
  client = OAuth2::Client.new(client_id,
                                client_secret,
                                token_url: "/oauth2/token",
                                site: "https://www.example.com/" )

  access_token = client.password.get_token(username, password)
  Rails.logger.info access_token.token
end

Here你可以找到类似的问题。

如果有人想使用简单的http方法获取具有密码凭据的访问令牌,下面是如何处理此事的示例:

def test
  param = {
          :client_id => client_id,
          :client_secret => client_secret,
          :grant_type => 'password',
          :username => username,
          :password => password
        }

  uri = URI.parse(service_url)
  http = Net::HTTP.new(uri.host, uri.port)
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  http.use_ssl = true
  request = Net::HTTP::Post.new(uri.request_uri)
  request.body = param.to_query
  response = http.request(request)

  Rails.logger.info response.body()
end