2016-10-02 76 views
1

我會盡量保持這一點儘可能簡短和重點。在Ruby中使用REST API - 何時進行身份驗證?

我正在寫一個Ruby Gem,仿照Diplomat gem,這是一個圍繞產品的REST API的包裝。我正在使用的API使用基於令牌的身份驗證; API令牌通過POST發送,並且會話作爲cookie返回。我正在使用法拉第cookiejar中間件來處理由API返回的cookie。在概念上,我正在努力的問題是何時進行身份驗證。

我有兩個類,一個叫RestClient,一個叫Volume;後者繼承前者。現在,RestClient的init方法構建一個連接對象並進行身份驗證,而Volume的init方法調用super並傳遞路徑。我的想法是,當從RestClient繼承的任何類被初始化時,它將認證用戶。

class RestClient 
    def initialize(api_path) 
    <build connection> 
    auth 
    end 
    def auth 
    <post token, get session cookie> 
    end 
end 

class Volume < RestClient 
    def initialize 
    super('/volume') 
    end 
    def volumes 
    <send GET, receive volumes> 
    end 
end 

obj = Volume.new #Creates object, authenticates user 
obj.volumes #Returns list of volumes 

我想我的問題是..am我走向正確的軌道?我是否應該暫緩認證直到首次在對象上調用方法,而不是在初始化時進行認證?我是否完全錯誤地回答了這個問題?

回答

0

你在這裏問的是更多的代碼風格的問題。這裏沒有對或錯。我正要投票結束,因爲我認爲它是primarily opinion-based

因爲我有意見,我正在寫一個答案。

一)不要過度想

剛剛實施的東西,如果它的工作原理,它是不夠好,

二)規則的3

,如果你已經實現了相同的3件事種類和模式出現,重構!

c)拒絕使用繼承

有疑問時,不要使用繼承。一個模塊在大多數情況下都會很好。

你的問題具體是:

我不會用一個初始化進行HTTP調用。它們很容易出錯,並且在初始化程序中或者在這些程序中的錯誤處理真的很難看。它使測試在屁股疼痛。

我會做的只是實現你需要的任何簡單的方法。

撥打authenticate之前撥打另一個api電話有什麼問題?把它變成一個模塊可以使它非常好的,可讀:

client.authenticate do |session| 
    session.volumes 
end 

,如果這是爲您的使用情況太醜陋,你能可能需要驗證任何其他方法調用之前做到這一點懶洋洋地。

+0

一個memoized AUTH我很欣賞的反饋,我很容易得太多。在每次調用API調用的方法之前,我都進行了懶惰的身份驗證,隨後使測試變得更加容易。我將這個標記作爲一個簡單的事實的答案,指出在初始化過程中進行身份驗證是一種不好的模式,單憑這一建議是一個很大的幫助。 – Alayde

0

Cookie是您的API支持的唯一身份驗證嗎?通常,面向服務器(服務器到服務器)的REST API還實施了更好的認證策略,允許您在每次請求時都通過認證。

之所以這麼說,你也可以做的是這樣的:

client = MyApi::Client.for_user(username: ..., password: ....) 
#...or 
client = MyApi::Client.for_token(token) 
volumes = MyApi::Volumes.get(client: client) 

這種方式對於需要身份驗證,你會通過做一件好事「鼓勵類使用權」 - 你根本不會在沒有驗證數據的情況下實例化客戶端,並且不會在沒有客戶端的情況下初始化遠程對象/調用。

之後,客戶端內,你所能做的就是在第一次請求

def perform(http_method, url, ...) 
    @auth_cookie ||= @client.get_cookie_by_authentication 
    ... 
end 
相關問題