It'd be really handy to know if this is correct or a bit off before I start doing this all over the place.
Im trying to set up an API and I want to be able to access current_user in my controllers. So I'm setting up some authentication, which i'm okay with it being basic for for now while i develop. I want to develop with tests and I've done this
spec/requests/api/v1/topics_spec.rb
RSpec.describe 'API::V1::Topics API', type: :request do
let!(:user) { create(:user, permission: "normal") }
let!(:user_encoded_credentials) { ActionController::HttpAuthentication::Basic.encode_credentials(user.email, user.password) }
let(:headers) { { "ACCEPT" => "application/json", Authorization: user_encoded_credentials } }
it 'returns some topics' do
get '/api/v1/topics', headers: headers
expect(response).to have_http_status(:success)
end
It seems a bit weird having to call "let!" for each user and encoded credentials at the top. I feel like there might be a better way but cant seem to find it by googling.
My plan is to add this code every time I create a test user so I can pass the correct basic authentication header with each request.
Heres the api_controller code if needed also:
app/controllers/api/v1/api_controller.rb
module Api
module V1
class ApiController < ActionController::Base
before_action :check_basic_auth
skip_before_action :verify_authenticity_token
private
def check_basic_auth
unless request.authorization.present?
head :unauthorized
return
end
authenticate_with_http_basic do |email, password|
user = User.find_by(email: email.downcase)
if user && user.valid_password?(password)
@current_user = user
else
head :unauthorized
end
end
end
def current_user
@current_user
end
end
end
end