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

 荒唐中带着正经_638 发布于 2023-01-12 11:33

我在我的Rails应用程序中使用omn​​iauth-coinbase和coinbase-ruby.

在我的应用程序中,用户通过Coinbase登录,生成一个code然后我转为a access_token和a refresh_token.

然后,我在变量下创建一个新的OAuth客户端coinbase,它具有完整的功能.

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)

这是问题开始的地方:

我存储access_tokenrefresh_token对用户模型作为字符串,以便当用户回来,我既可以使用两个活动令牌或使用refresh_token产生两个新的标记,如节中提到这里的"访问令牌和刷新令牌"

Coinbase公开了一个refresh!我可以在我的coinbaseOAuth实例上调用的方法,它应该给我两个新的标记.

refresh!正常工作后,我产生一个新的OAuth客户端,但不是当我拉从数据库中现有的标记(有效或无效)关闭用户模式,创建一个user_credentials哈希如上所述,实例化一个新的OAuth客户端,然后调用refresh!上.

据我所知,我的研究access_token到期了.我使用refresh_token随时随地获得新的access_token和新的refresh_token.所以在我看来,我应该能够实例化一个新的OAuth客户端,给它两个键并运行一个refresh!让我恢复正常工作并能够对Coinbase API进行有效调用.

任何人都可以帮助我解决我可能做错的事情吗?谢谢!

我得到的错误refresh!如下:

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 '
/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 '
/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 `
'

cookrn.. 5

通过我自己实现这一点,我既能重现所描述的异常,又能创建工作代码.

为了重现描述的异常,我不得不使用旧令牌.401 NOT AUTHORIZED尝试再次刷新时,这始终产生HTTP响应.这是通过在我自己的刷新代码中实现错误而发生的.虽然我已经成功地保留了从OAuth重定向返回的令牌,但是一旦我刷新了新令牌,我忘了将新的令牌保留回模型.注意:刷新令牌会为您提供新的access_tokenAND refresh_token返回.

接下来,我最终得到的工作代码如下:

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

完整的工作示例

令牌被保留在底部的用户身上,防止旧的/过期的令牌被使用.

最后,这可能是这个问题的重复,尽管它不那么具体.

1 个回答
  • 通过我自己实现这一点,我既能重现所描述的异常,又能创建工作代码.

    为了重现描述的异常,我不得不使用旧令牌.401 NOT AUTHORIZED尝试再次刷新时,这始终产生HTTP响应.这是通过在我自己的刷新代码中实现错误而发生的.虽然我已经成功地保留了从OAuth重定向返回的令牌,但是一旦我刷新了新令牌,我忘了将新的令牌保留回模型.注意:刷新令牌会为您提供新的access_tokenAND refresh_token返回.

    接下来,我最终得到的工作代码如下:

    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
    

    完整的工作示例

    令牌被保留在底部的用户身上,防止旧的/过期的令牌被使用.

    最后,这可能是这个问题的重复,尽管它不那么具体.

    2023-01-12 11:36 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有