2017-04-08 57 views
0

我在Elixir中实现了rest api。一个API密钥被传递给每个请求来验证用户。在一个插件我有这个:Phoenix中基于标头的REST API身份验证

defmodule MyApp.ApiSecurity do 
    def init(options) do 
    options 
    end 

def call(conn, _opts) do 
    # checking if "api-key" headers exists 
    # and key is valid 

    # .... what's next? 
    # if it's a) valid 
    # b) invalid or there's no "api-key" header 
    # ??? 
end 
end 

我知道如何实现它的状态和会话的正常,基于窗体的身份验证。但在休息api没有会话。那么,我该怎么办?换句话说,当a)api键有效时,函数的其余部分应该是什么“调用”b)无效?

回答

1

如果密钥无效或不存在,您通常会发送带有适当错误状态代码的错误消息,然后调用Plug.Conn.halt/1,这将阻止此请求继续通过插入管道。如果他们的密钥有效,那么您可能需要为conn(例如user_id)指定一些值,您的应用程序的其余部分可以使用该值。

例如:

def call(conn, _opts) do 
    case authenticate(conn) do 
    {:ok, user_id} -> 
     conn 
     |> assign(:user_id, user_id) 
    :error -> 
     conn 
     |> send_resp(401, "Unauthenticated") 
     |> halt() 
    end 
    end 
end 

现在,被这一个后插入任何插头可以肯定的是存在于conn.assigns有效user_id,可以利用它。

为了更真实世界的方式,你可以看到guardian如何做到这一点:

+0

肯定的,但是'|>分配(:USER_ID,USER_ID)'将其插入会话中。因此,它创建了一个状态。在哪里休息api不应该有一个国家,对吧? – Otoma

+0

'assign'不会插入会话中(即'put_session')。 'alloc'只会将值插入到内存'conn'中,一旦'conn'被垃圾收集(通常在响应发送给客户端之后),将永远删除任何值。 – Dogbert

+0

好的。那么我将如何从控制器访问该存储值? – Otoma