我正在Elixir中实现一个rest api。将向每个请求传递一个 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
我知道如何为具有状态和会话的基于表单的正常身份验证实现它。但是在 rest api 中没有会话。那么,我该怎么办?换句话说,当a(a(api密钥有效b(无效时,函数"调用"的其余部分应该是什么?
如果密钥无效或不存在,您通常会发送带有正确错误状态代码的错误消息,然后调用 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
如何做到这一点:
- Guardian.Plug.EnsureResource
- Guardian.Plug.ErrorHandler