我有一个与auth0服务集成的Rails后端api应用程序,该应用程序仅验证从前端应用程序接收到的auth_token的有效性。在保护了所有后端api端点之后,我所有的测试都失败了,结果是“未通过身份验证”,这应该是这样。但是,我无法弄清楚如何通过身份验证并且不要求对rspec测试进行身份验证。这是我的课程:
projects_controller_spec.rb
require "rails_helper"
RSpec.describe Api::V1::ProjectsController,:type => :controller do
describe 'GET /api/v1/organizations/1/projects' do
let!(:organization) { create(:organization_with_projects) }
before { get :index,params: { organization_id: organization } }
context 'when authorized' do
it 'should return JSON objects' do
expect(json['projects'].count).to equal(3)
end
it { expect(response).to have_http_status(:ok) }
it { expect(response.content_type).to include('application/json') }
end
describe 'POST /api/v1/organizations/1/projects' do
let!(:organization) { create(:organization) }
let(:project) { organization.projects.first }
before { post :create,params: { organization_id: organization,project: attributes_for(:project) } }
context 'when authorized' do
it { expect(response).to have_http_status(:created) }
it { expect(response.content_type).to include("application/json") }
it { expect(json).to eq(serialized(project)) }
end
end
end
application_controller.rb
class ApplicationController < actionController::API
include Pundit
include Secured
rescue_from activeRecord::RecordNotFound,:with => :record_not_found
private
def record_not_found(error)
render json: { error: error.message },status: :not_found
end
end
关注点/secured.rb
module Secured
extend activeSupport::Concern
included do
before_action :authenticate_request!
end
private
def authenticate_request!
# Create user if not existing
pundit_user
auth_token
rescue JWT::VerificationError,JWT::DecodeError
render json: { errors: ['Not Authenticated'] },status: :unauthorized
end
def http_token
if request.headers['Authorization'].present?
request.headers['Authorization'].split(' ').last
end
end
def auth_token
JsonWebToken.verify(http_token)
end
def pundit_user
User.create_from_token_payload({token: auth_token[0],organization_id:
request.parameters['organization_id']})
end
end
lib / json_web_token.rb
require 'net/http'
require 'uri'
class JsonWebToken
def self.verify(token)
JWT.decode(token,nil,true,# Verify the signature of this token
algorithm: 'RS256',iss: 'https://xxx.auth0.com/',verify_iss: true,aud: Rails.application.secrets.auth0_api_audience,verify_aud: true) do |header|
jwks_hash[header['kid']]
end
end
def self.jwks_hash
jwks_raw = Net::HTTP.get URI("https://xxx.auth0.com/.well-known/jwks.json")
jwks_keys = Array(JSON.parse(jwks_raw)['keys'])
Hash[
jwks_keys
.map do |k|
[
k['kid'],OpenSSL::X509::Certificate.new(
Base64.decode64(k['x5c'].first)
).public_key
]
end
]
end
end