2017-12-30 8 views
2

요청 사양을 인증하는 데 문제가 있습니다. 각 HTTP 요청 헤더에 유효한 인증 토큰을 어떻게 전달합니까? 내 접근법이 정확한 것보다 아래에 있습니까?각 http RSpec 테스트 헤더에 인증 토큰을 추가하는 방법

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 

여기에 내 인증 제어기 코드뿐만 아니라 생성하여 HTTP 헤더에서 전달 된 인증 토큰을 복호화 도움 모듈이다.

authentication_controller.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 

authorize_api_request.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 
+0

에서 조롱에 대한 자세한 내용을보실 수 있습니다 내가 사용자 인증을 추가하려면이 링크를 봤는데이 –

+0

를 구축하기 위해 사용하는 링크를 포함 : HTTPS : //www.pluralsight .com/guides/ruby-ruby-on-rails/토큰 기반 인증 - ruby-on-rails-5-api와 함께 – Jas1997

+1

덕분에 행운을 빌어 요 행복한 새해 –

답변

3

the official pluralsight page

엔드 포인트에서 복사 한 일부 코드 추출물 인증 할 수는 config/routes.rb

post 'authenticate', to: 'authentication#authenticate' 
01에

이 작업을 실행합니다. 올바르게 인증하면 조치가 토큰을 리턴합니다.

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 

rspec에는 두 가지 옵션이 있습니다.이 방법을 조롱하거나 공장을 만드십시오.

token based 인증의 개념은 한 번에 사용자가 토큰을 가지고 그 사용자 만

$ curl -H "Content-Type: application/json" -X POST -d '{"email":"[email protected]","password":"123123123"}' http://localhost:3000/authenticate 

이 제공 요청에 예약 된 기능에 액세스 할 수 있습니다이 토큰을 제공합니다 인증이다 토큰에 대한 응답으로

{"auth_token":"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA"} 

토큰 헤더에 토큰을 포함하면 요청에 의해 aut horization 오류

$ curl -H "Authorization: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE0NjA2NTgxODZ9.xsSwcPC22IR71OBv6bU_OGCSyfE89DvEzWfDU0iybMA" http://localhost:3000/items [] 

은 그래서 당신의 GET 요청을하기 전에, auth_token의 토큰

request.headers['Authorization'] = auth_token 
get :your_action 

방법을 제공하는 올바른 값을 헤더를 요청에 포함되어 있습니까? 그것은 당신이 인증 오류가 발생하지 않도록,이 코드 줄을 조롱한다 믿는 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 

before을 불리는

당신은, ApplicationControllermock 방법 authenticate_request해야합니다.

@current_user = AuthorizeApiRequest.call(request.headers).result 

그래서 내가 before_action를 사용하여

pluralsight을 인용 사양이

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 

같은 somethind 작성합니다, 서버는 전달 사용 request headers (내장 객체 속성 요청 .headers)를 AuthorizeApiRequest으로 변경하십시오. AuthorizeApiRequest.call(request.headers)result을 호출하는 것은 SimpleCommand 모듈에서 이루어지며 여기에서 attr_reader :result으로 정의됩니다. 요청 결과는 @current_user에 반환되므로 ApplicationController을 상속하는 모든 컨트롤러에서 사용할 수있게됩니다.

당신은

https://github.com/rspec/rspec-mocks

관련 문제