[英]How can I test authenticated APIs created using Rails 5?
我有一個使用Rails 5創建的需要身份驗證的API。身份驗證的基本流程是,用戶使用Base64編碼的Authorization: Basic
標頭中的用戶名/密碼以及API密鑰執行登錄。 然后將其交換為授權令牌,該令牌記錄在用戶數據庫表中,並且在一段時間內有效。 隨后的API調用需要在Authorization: Bearer
標頭中使用此令牌。
我遇到的問題是,當我嘗試測試需要身份驗證的控制器時,我必須經歷登錄用戶的過程(以確保auth_token
在測試數據庫表中,因為這可能是正在運行的第一個測試,等等。。。這很復雜,因為,例如,如果我正在測試一個名為RecipesController
的控制器,並且我的身份驗證位於AuthController
,則我需要切換控制器才能執行登錄東西。
過去,我已經在spec_helper.rb
成功完成了spec_helper.rb
操作:
def login username, password
current_controller = @controller
... setup login call ...
post :login
@controller = current_controller
... return auth token ...
end
但是,正如我在“ 為什么在Rails 5的測試中不傳遞參數”中所認識的那樣? ,我相信這會弄亂我的測試請求,結果導致參數丟失。
但是,這似乎是一種非常簡單的模式,因此,我想知道如何對其進行測試? 實際上,我更願意單獨測試身份驗證,只傳遞一個模擬的用戶對象,但是我不確定該怎么做,因為我對Rails的了解不如我想的那樣。
在ApplicationController中具有Auth驗證功能(假設您的食譜繼承自此)
def current_user
return nil unless auth_token
User.find(decoded_token['user_id'])
end
def authenticate_with_token
head(:unauthorized) unless user_signed_in?
end
private
def user_signed_in?
current_user.present?
end
def auth_token
return nil unless request.headers['Authorization'].present?
request.headers['Authorization']&.split(' ')&.last
end
def decoded_token
JsonWebToken.decode(auth_token) #use your own decoder class
end
然后,您可以在需要身份驗證的操作上添加before_action :authenticate_with_token
authenticate_with_token。
對於測試,您可以添加一個幫助程序來登錄用戶,這樣就不必在需要身份驗證的所有地方重復操作。
module LoginSupport
def login_user(user:, password:)
valid_credentials = { "email": user.email, password: password}
post '/auth/sessions', params: valid_credentials
valid_jwt_token = JSON.parse(response.body)["token"]
{ "Authorization": "Bearer #{valid_jwt_token}" }.merge(json_api_headers)
end
def json_api_headers
{'Accept' => JSONAPI::MEDIA_TYPE, 'CONTENT_TYPE' => JSONAPI::MEDIA_TYPE}
end
end
RSpec.configure do |config|
config.include LoginSupport
end
然后在RecipesContoller測試或其他任何位置的請求中使用返回的Auth令牌。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.