【问题标题】:Invalid access_token when using RSpec request specs to authorize a request使用 RSpec 请求规范授权请求时 access_token 无效
【发布时间】:2020-03-19 20:23:35
【问题描述】:

我正在尝试使用 RSpec 请求规范测试 CredentialsController,它在生产中运行良好。

代码

控制器

class CredentialsController < ApplicationController
  before_action :doorkeeper_authorize!
  def me
    render json: current_user
  end
end

GET /me 路由到CredentialsController#me。)

请求规格

describe 'Credentials', type: :request do
  context 'unauthorized' do
    it "should 401" do
      get '/me'
      expect(response).to have_http_status(:unauthorized)
    end
  end

  context 'authorized' do
    let!(:application) { FactoryBot.create(:application) }
    let!(:user)        { FactoryBot.create(:user) }
    let!(:token)       { FactoryBot.create(:access_token, application: application, resource_owner_id: user.id) }

    it 'succeeds' do
      get '/me', params: {}, headers: {access_token: token.token}
      expect(response).to be_successful
    end
  end
end

未授权测试通过,但授权测试失败:

预计#&lt;ActionDispatch::TestResponse:0x00007fd339411248 @mon_mutex=#&lt;Thread::Mutex:0x00007fd339410438&gt;, @mo..., @method=nil, @request_method=nil, @remote_ip=nil, @original_fullpath=nil, @fullpath=nil, @ip=nil&gt;&gt;.successful? 返回真,得到假

标头表示令牌有问题:

0> response.headers['WWW-Authenticate']
=> "Bearer realm=\"Doorkeeper\", error=\"invalid_token\", error_description=\"The access token is invalid\""

token 在我看来还不错,不过:

0> token
=> #<Doorkeeper::AccessToken id: 7, resource_owner_id: 8, application_id: 7, token: "mnJh2wJeEEDe0G-ukNIZ6oupKQ7StxJqKPssjZTWeAk", refresh_token: nil, expires_in: 7200, revoked_at: nil, created_at: "2020-03-19 20:17:26", scopes: "public", previous_refresh_token: "">

0> token.acceptable?(Doorkeeper.config.default_scopes)
=> true

工厂

访问令牌

FactoryBot.define do
  factory :access_token, class: "Doorkeeper::AccessToken" do
    application
    expires_in { 2.hours }
    scopes { "public" }
  end
end

应用

FactoryBot.define do
  factory :application, class: "Doorkeeper::Application" do
    sequence(:name) { |n| "Project #{n}" }
    sequence(:redirect_uri)  { |n| "https://example#{n}.com" }
  end
end

用户

FactoryBot.define do
  factory :user do
    sequence(:email) { |n| "email#{n}@example.com" }
    password { "test123" }
    password_confirmation { "test123" }
  end
end

问题

  • 为什么我会收到 invalid_token 这个请求?
  • 我的 Doorkeeper 工厂看起来正确吗?

【问题讨论】:

    标签: ruby-on-rails rspec doorkeeper


    【解决方案1】:

    我错误地传递了令牌。而不是:

    get '/me', params: {}, headers: {access_token: token.token}
    

    我不得不使用:

    get '/me', params: {}, headers: { 'Authorization': 'Bearer ' + token.token}
    

    【讨论】:

      【解决方案2】:

      您可以检查您的 Access Token 工厂的作用域,它应该与初始化器的 default_scopes 相同

      例如

      config/initializers/doorkeeper.rb

      default_scopes :read
      

      下面,你的 Access Token 工厂的作用域应该是

      factory :access_token, class: "Doorkeeper::AccessToken" do
        sequence(:resource_owner_id) { |n| n }
        application
        expires_in { 2.hours }
        scopes { "read" }
      end
      

      另外,如果你遇到响应状态:406 while get '/me'....

      表示不支持请求的格式(默认为 HTML)。您也可以在 HTTP 标头中发送 Accept="application/json" 来代替 '.json'。

      get '/me', params: {}, headers: { 
        'Authorization': 'Bearer ' + token.token, 
        'Accept': 'application/json'}
      

      我用这个解决方案解决了我的问题,也许你可以试试。

      【讨论】:

        猜你喜欢
        • 2018-10-16
        • 2019-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-14
        • 1970-01-01
        相关资源
        最近更新 更多