我按照本指南在我的Ruby On Rails应用程序中实现了Yandex Oauth。 几周我没有遇到任何问题,但最近(几天前)我遇到了问题。我无法获取访问令牌、刷新令牌等,因为我的请求失败并出现 400 错误代码。
我收到此特定消息:
{"error_description": "Code has expired", "error": "invalid_grant"}
从指南:
此代码的生命周期为 10 分钟。当它过期时,代码必须 再次请求。
但它从不等待 10 分钟甚至 10 秒,因为一旦我的应用程序获得授权代码,它就会立即发出 POST 请求以更改访问令牌、刷新令牌和过期的此授权代码。但是此 POST 请求失败,因为该授权代码似乎已过期。
来自Yandex错误描述:
invalid_grant ― 授权码无效或过期。
我的代码:
def yandex
require 'net/http'
require 'json' # => false
@user = User.from_omniauth(request.env["omniauth.auth"])
@client_id = Rails.application.secrets.client_id
@secret = Rails.application.secrets.password
@authorization_code = params[:code]
@user.update_attribute(:code, @authorization_code)
@user.update_attribute(:state, params[:state])
@post_body = "grant_type=authorization_code&code=#{@authorization_code}&client_id=#{@client_id}&client_secret=#{@secret}"
@url = "https://oauth.yandex.ru/token"
url = URI.parse(@url)
req = Net::HTTP::Post.new(url.request_uri)
req['host'] ="oauth.yandex.ru"
req['Content-Length'] = @post_body.length
req['Content-Type'] = 'application/x-www-form-urlencoded'
req.body = @post_body
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = (url.scheme == "https")
@response_mess = http.request(req)
refreshhash = JSON.parse(@response_mess.body)
access_token = refreshhash['access_token']
refresh_token = refreshhash['refresh_token']
access_token_expires_at = DateTime.now + refreshhash["expires_in"].to_i.seconds
if access_token.present? && refresh_token.present? && access_token_expires_at.present?
@user.update_attribute(:access_token, access_token)
@user.update_attribute(:refresh_token, refresh_token)
@user.update_attribute(:expires_in, access_token_expires_at)
sign_in(@user)
redirect_to admin_dashboard_index_path
end
end
我的日志:
Started GET "/users/auth/yandex/callback?state=31c11a86beecdeb55ab30887d56391a8cbafccdc85c456aa&code=5842278" for 212.3.192.116 at 2017-04-05 15:58:27 +0300
Cannot render console from 212.3.192.116! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by CallbacksController#yandex as HTML
Parameters: {"state"=>"31c11a86beecdeb55ab30887d56391a8cbafccdc85c456aa", "code"=>"5842278"}
我在 CHROME POSTMAN 中尝试了相同的 POST 请求,并收到了与{"error_description": "Code has expired", "error": "invalid_grant"}
相同的响应
我已经用谷歌搜索过,但没有任何类似的问题。似乎问题出在Yandex端,但是如何解决呢?
任何帮助将不胜感激。
Yandex授权码是一次性的。您确定您没有两次请求"https://oauth.yandex.ru/token"吗?您可以尝试在Chrome Postman中发出此类请求,然后再评估执行相同操作的代码。