2016-10-02 108 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 
相关问题