我正在使用Guardian并尝试使用Canary但是,我似乎无法获取当前用户,canary需要conn.assigns中的current_user,我已经遵循了this,如果我要求(在控制器操作内):
Guardian.Plug.authenticated?(conn)
我说的是真的,但如果我这样做:
Guardian.Plug.current_resource(conn)
只是一片空白。
我的 api 管道中有这段代码:
pipeline :private_api do
plug :accepts, ["json"]
plug Guardian.Plug.LoadResource
plug Guardian.Plug.VerifyHeader
plug Guardian.Plug.EnsureAuthenticated, handler: SessionController
plug MyApp.Plug.CurrentUser
end
以及 MyApp.Plug.CurrentUser
defmodule MyApp.Plug.CurrentUser do
def init(opts), do: opts
def call(conn, _opts) do
current_user = Guardian.Plug.current_resource(conn)
Plug.Conn.assign(conn, :current_user, current_user)
end
end
Session创建方法:
def create(conn, %{"session" => session_params}) do
case MyApp.Session.authenticate(session_params) do
{:ok, user} ->
{:ok, jwt, _full_claims} = user |> Guardian.encode_and_sign(:token)
Plug.Conn.assign(conn, :current_user, user)
conn
|> put_status(:created)
|> render("show.json", jwt: jwt, user: user)
:error ->
conn
|> put_status(:unprocessable_entity)
|> render("error.json")
end
end
也许我只是错过了一些东西。
编辑:
我通过像这样更改 MyApp.Plug.CurrentUser 来使其工作:
defmodule MyApp.Plug.CurrentUser do
alias MyApp.GuardianSerializer
def init(opts), do: opts
def call(conn, _opts) do
current_token = Guardian.Plug.current_token(conn)
case Guardian.decode_and_verify(current_token) do
{:ok, claims} ->
case GuardianSerializer.from_token(claims["sub"]) do
{:ok, user} ->
Plug.Conn.assign(conn, :current_user, user)
{:error, _reason} ->
conn
end
{:error, _reason} ->
conn
end
end
end
虽然它有效,但也许有更好的方法或其他方法,例如使用sign_in。
对于最新版本的
Guardian
,这是工作代码:
defmodule MyApp.Plugs.CurrentUser do
def init(opts), do: opts
def call(conn, _opts) do
current_token = Guardian.Plug.current_token(conn)
case MyApp.Guardian.resource_from_token(current_token) do
{:ok, user, claims} ->
Plug.Conn.assign(conn, :current_user, user)
{:error, _reason} ->
conn
end
end
end
根据文档,这就是 pipline 的配置方式:
defmodule MyApp.AuthAccessPipeline do
use Guardian.Plug.Pipeline, otp_app: :my_app
plug Guardian.Plug.VerifySession, claims: %{"typ" => "access"}
plug Guardian.Plug.VerifyHeader, claims: %{"typ" => "access"}
plug Guardian.Plug.EnsureAuthenticated
plug Guardian.Plug.LoadResource, allow_blank: true
end
您的管道中缺少
Guardian.Plug.LoadResource
。
仔细阅读文档。