简体   繁体   English

在用户模型上存储access_token和refresh_token并再次使用它们会导致错误

[英]Storing an access_token and refresh_token on the user model and using them again causes error

I'm using omniauth-coinbase and coinbase-ruby in my Rails app. 我在Rails应用程序中使用omn​​iauth-coinbasecoinbase-ruby

In my app, the user logs in via Coinbase which generates a code which I then turn into an access_token and a refresh_token . 在我的应用程序中,用户通过Coinbase登录,该Coinbase生成一个code ,然后我将其变成access_tokenrefresh_token

I then create a new OAuth Client under the variable coinbase and it has full functionality. 然后,我在变量coinbase下创建一个新的OAuth Client,它具有完整的功能。

user_credentials = {
    :access_token => access_token,
    :refresh_token => refresh_token,
    :expires_at => Time.now + 1.day
}
coinbase = Coinbase::OAuthClient.new(ENV['COINBASE_CLIENT_ID'], ENV['COINBASE_CLIENT_SECRET'], user_credentials)

Here's where the problem starts: 这是问题开始的地方:

I'm storing the access_token and the refresh_token on the User model as strings so that when the user comes back, I can either use two active tokens or use the refresh_token to generate two new tokens, as mentioned in section here "Access Tokens and Refresh Tokens" 我存储access_tokenrefresh_token上的用户模型作为字符串,以便当用户回来,我既可以使用两个活动令牌或使用refresh_token产生两个新的标记,如节中提到这里 “访问令牌和刷新令牌”

Coinbase exposes a refresh! Coinbase展示了refresh! method that I can call on my coinbase OAuth instance which should give me two new tokens. 我可以在我的coinbase OAuth实例上调用的方法,该实例应该给我两个新令牌。

refresh! works correctly after I generate a new OAuth Client but not when I pull existing tokens (valid or invalid) from the database off of the user model, create a user_credentials hash as noted above, instantiate a new OAuth Client, and then call refresh! 正常工作后,我产生一个新的OAuth客户端而不是当我拉从数据库中现有的标记(有效或无效)关闭用户模式,创建一个user_credentials散列如上所述,实例化一个新的OAuth客户端,然后调用refresh! on that. 在那。

As I understand from my research, the access_token expires. 据我的研究了解, access_token过期了。 I use a refresh_token whenever to get both a new access_token and a new refresh_token . 每当获取新的access_token和新的refresh_token时,我都会使用refresh_token So in my mind, I should be able to instantiate a new OAuth Client, give it both keys and run a refresh! 因此,在我看来,我应该能够实例化一个新的OAuth客户端,为其提供两个密钥并运行refresh! to put me back in working order and able to make valid calls to the Coinbase API. 使我恢复正常工作,并能够对Coinbase API进行有效调用。

Can anyone help out here as to what I may be doing wrong? 有人可以帮我解决我可能做错的事情吗? Thanks! 谢谢!

There error that I get from refresh! 我从refresh!得到错误refresh! is as follows: 如下:

OAuth2::Error: invalid_request: The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.
{"error":"invalid_request","error_description":"The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed."}
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/gems/oauth2-0.9.4/lib/oauth2/client.rb:113:in `request'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/gems/oauth2-0.9.4/lib/oauth2/client.rb:138:in `get_token'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/gems/oauth2-0.9.4/lib/oauth2/access_token.rb:86:in `refresh!'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/gems/coinbase-2.0.0/lib/coinbase/oauth_client.rb:58:in `refresh!'
/Users/zackshapiro/dev/stopcoin/lib/tasks/short.rake:14:in `block (3 levels) in <top (required)>'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/gems/activerecord-4.1.0/lib/active_record/relation/delegation.rb:46:in `each'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/gems/activerecord-4.1.0/lib/active_record/relation/delegation.rb:46:in `each'
/Users/zackshapiro/dev/stopcoin/lib/tasks/short.rake:6:in `block (2 levels) in <top (required)>'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/bin/ruby_executable_hooks:15:in `eval'
/Users/zackshapiro/.rvm/gems/ruby-2.0.0-p451/bin/ruby_executable_hooks:15:in `<main>'

By implementing this on my own, I was both able to reproduce the described exception as well as create working code. 通过自己实现这一点,我既可以重现所描述的异常,也可以创建工作代码。

To reproduce the described exception, I had to use old tokens . 要重现所描述的异常,我必须使用旧标记 This consistently produced a 401 NOT AUTHORIZED HTTP response when attempting to refresh again. 尝试再次刷新时,这始终会产生401 NOT AUTHORIZED HTTP响应。 This came about on accident by implementing a bug in my own refresh code. 这是通过在我自己的刷新代码中实现一个错误而偶然发生的。 Although I had successfully persisted the tokens returned from the OAuth redirect, once I had refreshed to new tokens once, I forgot to persist the new ones back to the model. 尽管我已经成功地保留了从OAuth重定向返回的令牌,但是一旦刷新一次新的令牌,便忘记了将新的令牌保留回模型。 NOTE: Refreshing the token gives you both a new access_token AND refresh_token back. 注意:刷新令牌可以同时返回新的access_tokenrefresh_token

Moving forward, the working code that I ended up with is as follows: 展望未来,我最终得到的工作代码如下:

def test_refresh
  @old_tokens =
    {
      :access_token  => current_user.access_token,
      :refresh_token => current_user.refresh_token
    }

  client =
    Coinbase::OAuthClient.new \
      Rails.application.secrets.coinbase_api_key,
      Rails.application.secrets.coinbase_api_secret,
      @old_tokens

  new_token = client.refresh!

  @new_tokens =
    {
      :access_token  => new_token.token,
      :refresh_token => new_token.refresh_token
    }

  current_user.access_token  = @new_tokens[ :access_token ]
  current_user.refresh_token = @new_tokens[ :refresh_token ]
  current_user.save!
end

FULL WORKING EXAMPLE 完整的示例

The tokens are being persisted back to the user at the bottom, preventing old/expired tokens from being used. 令牌将被持久保留在底部的用户手中,从而防止使用旧的/过期的令牌。

Lastly, this may be a duplicate of this question , though it is much less specific. 最后,这可能是该问题的重复部分,尽管它的具体程度要低得多。

I'm not able to reproduce this error. 我无法重现此错误。 Have you tried printing out all the relevant values before the call to Coinbase::OAuthClient.new? 在调用Coinbase :: OAuthClient.new之前,您是否尝试过打印所有相关值? Make sure the client_id, client_secret, and user_credentials are all present and correct. 确保client_id,client_secret和user_credentials都存在并且正确。

Also, it might be easier to just serialize the credentials hash directly to your User model. 同样,将凭据哈希直接直接序列化到您的用户模型可能会更容易。 Check out our example rails app at https://github.com/coinbase/coinbase-oauth-rails-example for reference. https://github.com/coinbase/coinbase-oauth-rails-example上查看我们的示例Rails应用程序以供参考。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM