Jas*_*997 3 ruby rspec ruby-on-rails http-headers
我在尝试验证请求规范时遇到问题。如何在每个 http 请求的标头中传递有效的身份验证令牌?我下面的方法正确吗?
tweets_request_spec.rb
require 'rails_helper'
RSpec.describe 'Tweets API', type: :request do
before do
@tweets = create_list(:tweet, 10)
@tweet = @tweets.first
end
describe 'GET /tweets' do
before { get '/tweets', { "Authorization": *some sort of token*} }
it "returns tweets" do
expect(json).to_not be_empty
expect(json).to eq(10)
end
it "is a successful http request" do
expect(response).to have_http_response(200)
end
end
end
Run Code Online (Sandbox Code Playgroud)
这是我的身份验证控制器代码,以及帮助生成和解码在 http 标头中传递的身份验证令牌的模块。
身份验证控制器.rb
class AuthenticationController < ApplicationController
skip_before_action :authenticate_request
def authenticate
command = AuthenticateUser.call(params[:email], params[:password])
if command.success?
render json: { auth_token: command.result }
else
render json: { error: command.errors }, status: :authorized
end
end
end
Run Code Online (Sandbox Code Playgroud)
授权_api_请求.rb
class AuthorizeApiRequest
prepend SimpleCommand
def initialize(headers = {})
@headers = headers
end
def call
user
end
private
attr_reader :headers
def user
@user ||= User.find(decoded_auth_token[:user_id]) if decoded_auth_token
@user ||= errors.add(:token, 'Invalid token') && nil
end
#decode the auth token and retrieve the user id
def decoded_auth_token
@decoded_auth_token ||= JSONWebToken.decode(http_auth_header)
end
#retrieve auth token from header
def http_auth_header
if headers['Authorization'].present?
return headers['Authorization'].split(' ').last
else
errors.add(:token, 'Missing token')
end
end
end
Run Code Online (Sandbox Code Playgroud)
从官方pluralsight页面复制的一些代码摘录
要进行身份验证的端点位于config/routes.rb
post 'authenticate', to: 'authentication#authenticate'
Run Code Online (Sandbox Code Playgroud)
执行此操作。如果您的身份验证正确,该操作将返回令牌。
def authenticate
command = AuthenticateUser.call(params[:email], params[:password])
if command.success?
render json: { auth_token: command.result }
else
render json: { error: command.errors }, status: :unauthorized
end
end
Run Code Online (Sandbox Code Playgroud)
在 rspec 中你有两个选择,要么模拟这个方法,要么创建一个工厂。
身份验证的概念token based是,一旦通过身份验证,用户将拥有一个令牌,通过提供此令牌,他将能够访问仅为用户保留的功能
请求
$ curl -H "Content-Type: application/json" -X POST -d '{"email":"example@mail.com","password":"123123123"}' http://localhost:3000/authenticate
Run Code Online (Sandbox Code Playgroud)
给出响应令牌
{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA"}
Run Code Online (Sandbox Code Playgroud)
如果您在标头中包含令牌,则请求将不会触发授权错误
$ curl -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA" http://localhost:3000/items []
Run Code Online (Sandbox Code Playgroud)
因此,在执行 get 请求之前,请在请求标头中包含令牌
request.headers['Authorization'] = auth_token
get :your_action
Run Code Online (Sandbox Code Playgroud)
如何提供正确的值auth_token?
您需要模拟authenticate_request中的方法ApplicationController,因为它被before称为action
#app/controllers/application_controller.rb
class ApplicationController < ActionController::API
before_action :authenticate_request
attr_reader :current_user
private
def authenticate_request
@current_user = AuthorizeApiRequest.call(request.headers).result
render json: { error: 'Not Authorized' }, status: 401 unless @current_user
end
end
Run Code Online (Sandbox Code Playgroud)
我相信您应该模拟这行代码,以避免收到身份验证错误。
@current_user = AuthorizeApiRequest.call(request.headers).result
Run Code Online (Sandbox Code Playgroud)
所以我会写这样的规格
user = FactoryBot.create(:user)
allow(AuthorizeApiRequest).to receive(:call).and_return(user)
# request.headers['Authorization'] = auth_token # this is not required anymore the authentication is skipped
get :your_action
Run Code Online (Sandbox Code Playgroud)
我引用复数观点
通过使用 before_action,服务器会在用户每次发出请求时传递
request headers(使用内置对象属性 request.headers) 。AuthorizeApiRequest调用result来自定义为 的AuthorizeApiRequest.call(request.headers)模块。请求结果返回到,从而可供所有继承自 的控制器使用。SimpleCommandattr_reader :result@current_userApplicationController
您可以阅读有关嘲笑的更多信息
https://github.com/rspec/rspec-mocks
| 归档时间: |
|
| 查看次数: |
2681 次 |
| 最近记录: |