我在RSpec中对其进行测试时,无法在标头参数中使用JWT令牌授权我的应用。我尝试手动创建令牌,并在请求标头中使用它进行授权,但RSpec说我没有被授权。有人可以告诉我这是什么错误吗?
我的RSpec测试出现此错误:
require 'rails_helper'
RSpec.describe "Api::V1::Users", type: :request do
let(:user) { create(:user, password: "password", password_confirmation: "password") }
let (:token_new) { Users::CreateTokenService.call(user)}
let(:token) do
{ "Authorization": "Bearer #{token_new}" }
end
describe "GET api/v1/user#show" do
context "correct params are passed" do
subject { get api_v1_user_path( format: :json, params: {}, headers: token ) }
it "returns correct status" do
subject
expect(response).to have_http_status(200)
end
end
end
end
创建令牌的服务:
module Users
class CreateTokenService < ApplicationService
attr_accessor :user
def initialize(user)
@user = user
end
def call
user.update_attribute(:jti, SecureRandom.uuid)
time = Time.now.to_i + 4 * 3600
payload = { user_id: user.id, exp: time, jti: user.jti }
token = JWT.encode(payload, Rails.application.secrets.secret_key_base)
end
end
end
api / v1 / users_controller.rb中的用户控制器:
module Api
module V1
class UsersController < BaseController
skip_before_action :require_login, only: %i[create]
def index
users = User.search(params[:search]).limit(10)
render :index, locals: { users: users }
end
def create
user = User.new(user_params)
if user.save
token = Users::CreateTokenService.call(user)
render partial: 'api/v1/users/user', locals: { user: user }, status: 201
response.set_header('Authorization: Bearer', token)
else
render json: { errors: user.errors.full_messages }, status: 422
end
end
def show
render partial: 'api/v1/users/user', locals: { user: session_user }, status: 200
end
private
def user_params
params.permit(:email, :password, :first_name, :last_name)
end
end
end
end
和RSpec错误:
1) Api::V1::Users GET api/v1/user#show correct params are passed returns correct status
Failure/Error: expect(response).to have_http_status(200)
expected the response to have status code 200 but it was 401
乍看之下,我看到的问题与您的subject
中的GET请求有关。您有:
get api_v1_user_path( format: :json, params: {}, headers: token )
但是param
和headers
应该是get
方法的选项,而不是api_v1_user_path
方法。应该是:
get api_v1_user_path(format: :json), params: {}, headers: token
另一面说明-对于Ruby哈希语法,您应该任一个将string键与火箭运算符(=>
)或symbol键与冒号运算符([C0 ])。您在此处使用带冒号的string:
:
因此Ruby将{ "Authorization": "Bearer #{token_new}" }
视为symbol,并被评估为:
"Authorization"
我想在这种情况下RSpec可以处理任何一种方式,但是为了将来参考,如果使用字符串键,则需要使用火箭:
{ Authorization: "Bearer #{token_new}" }