我对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."
请在这些设置中告知可能导致问题的原因。
答案 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