Guardian从v0.14升级至v1.0:Guardian.Plug.current_resource(conn)返回nil问题
Guardian v0.14 → v1.0 升级后
Guardian.Plug.current_resource(conn) 返回 nil 的排查方案 我最近在把Guardian从v0.14版本升级到v1.0版本,严格跟着官方升级指南走,但碰到了一个棘手的问题——调整完认证逻辑后,Guardian.Plug.current_resource(conn) 一直返回 nil。
原认证逻辑代码是这样的:
case Myapp.Session.authenticate(session_params) do {:ok, user} -> {:ok, jwt, _full_claims} = user |> Guardian.encode_and_sign(:token) conn |> put_status(:created) |> render("show.json", jwt: jwt, user: user) :error -> conn |> put_status(:unprocessable_entity) |> render("error.json") end
针对这个问题,我整理了几个高频排查点和修复方案:
1. 先检查 encode_and_sign 的调用格式
Guardian v1.0对encode_and_sign的参数做了强制调整,旧版本的:token类型标识不再生效,必须使用明确的类型(比如:access或:refresh),同时需要传入claims参数(空map也可以)。
修复后的代码应该是这样的:
# 使用默认Guardian模块的写法 {:ok, jwt, _full_claims} = Guardian.encode_and_sign(user, :access, %{}) # 如果你自定义了Guardian模块(推荐做法) {:ok, jwt, _full_claims} = Myapp.Guardian.encode_and_sign(user, :access, %{})
2. 同步更新Plug链配置
v1.0的Guardian Plug组件有不少变动,比如原有的VerifySession、LoadResource的行为和配置方式都变了。确保你的router或endpoint里的Plug链是正确的:
# 示例:正确的Guardian Plug加载顺序 plug Guardian.Plug.VerifyHeader, realm: "Bearer" plug Guardian.Plug.VerifySession plug Guardian.Plug.LoadResource, allow_blank: true
同时别忘了在config.exs里配置好你的Guardian模块(如果是自定义的):
config :myapp, Myapp.Guardian, issuer: "myapp", secret_key: "your_secret_key_here", allowed_algos: ["HS512"], ttl: {30, :days}, verify_issuer: true
3. 确认 current_resource 的调用时机
一定要在Guardian Plug处理过的conn上调用Guardian.Plug.current_resource(conn)。比如,要在controller的action里调用,而不是在路由匹配前,或者在没有经过验证的中间件里调用——否则conn里还没加载资源,自然返回nil。
4. 检查资源序列化的配置
Guardian v1.0依赖sub字段来从claims中反序列化资源,确保:
- 你的User模块实现了
Guardian.Token相关的协议(或者旧版的Guardian.Serializer,但v1.0推荐用新协议) - 调用
encode_and_sign时,claims里包含正确的sub值(比如用户ID)
如果是自定义claims,手动指定sub的示例:
{:ok, jwt, _full_claims} = Guardian.encode_and_sign(user, :access, %{sub: user.id})
内容的提问来源于stack exchange,提问作者D.R
相关产品推荐
相关产品推荐

