2017-04-08 56 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