Ueberauth/Guardian 从 0.14.x 升级到 1.0 的完整指南

Ueberauth/Guardian 从 0.14.x 升级到 1.0 的完整指南

guardian Elixir Authentication guardian 项目地址: https://gitcode.com/gh_mirrors/gu/guardian

前言

Ueberauth/Guardian 是一个强大的 Elixir 身份验证库,在 1.0 版本中进行了重大架构调整。本文将从技术实现角度,详细介绍从 0.14.x 升级到 1.0 版本的关键变化和迁移步骤。

核心架构变化

1.0 版本最大的变化是解耦了与 JWT 的强绑定关系,虽然默认仍提供完整的 JWT 功能,但现在已经支持自定义令牌类型。同时移除了对 Phoenix 和 Plug 的强制依赖,使得 Guardian 可以更独立地使用。

实现模块的引入

在 0.14.x 中,Guardian 是全局唯一的实现。1.0 版本要求开发者定义一个专门的模块来存放所有认证相关的配置和逻辑。

创建实现模块

defmodule MyApp.Guardian do
  use Guardian, otp_app: :my_app
  
  # 这里添加你的认证逻辑
end

这个模块将作为序列化器,同时也是放置 Hooks 的地方。

配置变更

配置方式有了显著改进,现在支持更灵活的配置值定义:

  • 可以指定模块函数调用:{MyModule, :func, [:some, :args]}
  • 也可以直接使用静态值

配置位置变化

0.14.x 版本:

config :guardian, Guardian,
  # 配置项

1.0 版本:

config :my_app, MyApp.Guardian,
  # 配置项

新增的重要配置项包括:

  • token_verify_module:验证声明的模块
  • token_ttl:令牌生存时间的映射 %{<token_type> => <ttl_value>}

序列化器重命名

0.14.x 中的 from_tokenfor_token 函数已被重命名并移动到实现模块中:

defmodule MyApp.Guardian do
  use Guardian, otp_app: :my_app

  def subject_for_token(resource, _claims) do
    {:ok, to_string(resource.id)}
  end

  def resource_from_claims(claims) do
    {:ok, find_me_a_resource(claims["sub"])}
  end
end

新函数名 subject_for_tokenresource_from_claims 更加语义化,且接收的参数更完整。

令牌操作变更

创建和验证令牌

0.14.x:

Guardian.encode_and_sign(resource, [token_type, claims])
Guardian.decode_and_verify(token, [claims_to_check])

1.0:

MyApp.Guardian.encode_and_sign(resource, [claims, options])
MyApp.Guardian.decode_and_verify(token, [claims_to_check, options])

令牌类型指定

0.14.x:

Guardian.encode_and_sign(resource, "other_type")

1.0:

MyApp.Guardian.encode_and_sign(resource, %{}, token_type: "other_type")

TTL 设置

0.14.x:

Guardian.encode_and_sign(resource, %{ttl: {1, :hour}})

1.0:

MyApp.Guardian.encode_and_sign(resource, %{}, token_ttl: {1, :hour})

管道(Pipeline)系统

1.0 版本引入了管道概念,用于定义认证流程:

defmodule MyApp.Guardian.AuthPipeline do
  @claims %{typ: "access"}

  use Guardian.Plug.Pipeline, 
    otp_app: :my_app,
    module: MyApp.Guardian,
    error_handler: MyApp.Guardian.AuthErrorHandler

  plug Guardian.Plug.VerifySession, claims: @claims
  plug Guardian.Plug.VerifyHeader, claims: @claims, realm: "Bearer"
  plug Guardian.Plug.EnsureAuthenticated
  plug Guardian.Plug.LoadResource, allow_blank: false
end

这个管道会:

  1. 从会话或头部查找令牌
  2. 验证令牌类型必须为 "access"
  3. 确保找到令牌
  4. 加载令牌对应的资源

错误处理简化

错误处理模块被大幅简化,现在只需要实现一个函数:

auth_error(conn, {failure_type, reason}, opts)

内置的错误类型包括:

  • :invalid_token
  • :unauthorized
  • :unauthenticated
  • :already_authenticated
  • :no_resource_found

自定义声明

1.0 版本提供了更灵活的自定义声明方式,可以在实现模块中添加 build_claims 回调:

def build_claims(claims, resource, opts) do
  new_claims = do_things_to_claims(claims)
  {:ok, claims}
end

钩子(Hooks)系统

Hooks 模块已被移除,改为在实现模块中定义回调函数:

  • after_encode_and_sign
  • after_sign_in
  • before_sign_out
  • on_verify
  • on_revoke
  • on_refresh
  • on_exchange
  • build_claims

WebSocket/Channel 支持

Phoenix Socket 和 Channel 的宏已被移除,改为提供一组轻量级函数:

defmodule MyApp.UserSocket do
  use Phoenix.Socket

  def connect(%{"guardian_token" => token}, socket) do
    case Guardian.Phoenix.Socket.authenticate(socket, MyApp.Guardian, token) do
      {:ok, authed_socket} -> {:ok, authed_socket}
      {:error, _} -> :error
    end
  end
end

权限系统改进

权限系统现在是可选的,并改名为更清晰的 Guardian.Permissions.Bitwise

定义权限

use Guardian, otp_app: :my_app,
             permissions: %{
               user_actions: %{
                 books: 0b1,
                 fitness: 0b100,
                 music: 0b1000
               }
             }
use Guardian.Permissions.Bitwise

使用权限

# 检查所有权限
has_all? = Guardian.all_permissions?(claims, %{user_actions: [:books]})

# 检查任意权限
has_any? = Guardian.any_permissions?(claims, %{user_actions: [:books, :music]})

在 Plug 中使用

plug Guardian.Permissions.Bitwise, ensure: %{user_actions: [:books]}

总结

1.0 版本带来了更灵活的架构设计,虽然需要一定的迁移工作,但提供了更好的扩展性和更清晰的API设计。建议开发者仔细测试迁移后的系统,特别是自定义声明和权限相关的功能。

guardian Elixir Authentication guardian 项目地址: https://gitcode.com/gh_mirrors/gu/guardian

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葛月渊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值