Project Icon

assent

轻量级多提供商身份认证框架 支持OAuth和OpenID Connect

Assent是一个多提供商身份认证框架,支持OAuth和OpenID Connect协议。框架内置20多种认证策略,涵盖Google、Facebook、GitHub等主流平台。Assent提供灵活配置,支持自定义HTTP客户端和JWT适配器,便于开发者将第三方身份验证集成到Elixir应用中。

Assent

Github CI hexdocs.pm hex.pm

多提供商认证框架。

特性

  • 包含以下基础策略:
    • OAuth 1.0 - Assent.Strategy.OAuth
    • OAuth 2.0 - Assent.Strategy.OAuth2
    • OpenID Connect - Assent.Strategy.OIDC
  • 包含以下提供商策略:
    • Apple 登录 - Assent.Strategy.Apple
    • Auth0 - Assent.Strategy.Auth0
    • Azure AD - Assent.Strategy.AzureAD
    • Basecamp - Assent.Strategy.Basecamp
    • DigitalOcean - Assent.Strategy.DigitalOcean
    • Discord - Assent.Strategy.Discord
    • Facebook - Assent.Strategy.Facebook
    • Github - Assent.Strategy.Github
    • Gitlab - Assent.Strategy.Gitlab
    • Google - Assent.Strategy.Google
    • Instagram - Assent.Strategy.Instagram
    • LINE 登录 - Assent.Strategy.LINE
    • Linkedin - Assent.Strategy.Linkedin
    • Spotify - Assent.Strategy.Spotify
    • Strava - Assent.Strategy.Strava
    • Slack - Assent.Strategy.Slack
    • Stripe Connect - Assent.Strategy.Stripe
    • Twitter - Assent.Strategy.Twitter
    • VK - Assent.Strategy.VK

安装

mix.exs 中将 Assent 添加到依赖列表:

defp deps do
  [
    # ...
    {:assent, "~> 0.2.9"}
  ]
end

运行 mix deps.get 进行安装。

HTTP 客户端安装

默认情况下,如果您的依赖列表中有 Req,则会使用它。否则,将使用 Erlang 的 :httpc

如果您使用 :httpc,应该添加以下依赖项以启用 SSL 验证:

defp deps do
  [
    # ...
    # 使用 :httpc 适配器时,需要进行 SSL 验证
    {:certifi, "~> 2.4"},
    {:ssl_verify_fun, "~> 1.1"}
  ]
end

您还必须在 mix.exs 中将 :inets 添加到 :extra_applications

def application do
  [
    # ...
    extra_applications: [
      # ...
      :inets
    ]
  ]
end

如果您使用其他 HTTP 适配器(如 ReqFinch),则无需进行此操作。

入门

策略包含两个阶段:请求和回调。在请求阶段,通常会将用户重定向到提供商进行认证,然后返回以启动回调阶段。

单一提供商示例

defmodule ProviderAuth do
  import Plug.Conn

  alias Assent.{Config, Strategy.Github}

  @config [
    client_id: "替换为客户端 ID",
    client_secret: "替换为客户端密钥",
    redirect_uri: "http://localhost:4000/auth/github/callback"
  ]

  # http://localhost:4000/auth/github
  def request(conn) do
    @config
    |> Github.authorize_url()
    |> case do
      {:ok, %{url: url, session_params: session_params}} ->
        # 会话参数(用于 OAuth 2.0 和 OIDC 策略)将在用户返回回调阶段时被检索
        conn = put_session(conn, :session_params, session_params)
```elixir
# 重定向终端用户到 Github 以授权访问其账户
conn
|> put_resp_header("location", url)
|> send_resp(302, "")

{:error, error} ->
  # 生成请求授权 URL 时出现问题
end
end

# http://localhost:4000/auth/github/callback
def callback(conn) do
# 终端用户将返回到带有附加参数的回调 URL。
# 这些参数必须传递给策略。在此示例中,我们只
# 期望 GET 查询参数,但提供者也可能通过
# POST 请求返回用户,其中参数在 POST 正文中。
%{params: params} = fetch_query_params(conn)

# 请求阶段存储的会话参数(用于 OAuth 2.0 和 OIDC 策略)
# 将在回调阶段使用
session_params = get_session(conn, :session_params)

@config
# 应将会话参数添加到配置中,以便策略可以使用它们
|> Config.put(:session_params, session_params)
|> Github.callback(params)
|> case do
  {:ok, %{user: user, token: token}} ->
    # 授权成功

  {:error, error} ->
    # 授权失败
end
end
end

多提供者示例

这是一个通用流程,类似于 PowAssent 中使用的流程。

config :my_app, :strategies,
github: [
  client_id: "替换为客户端ID",
  client_secret: "替换为客户端密钥",
  strategy: Assent.Strategy.Github
],
# ...
defmodule MultiProviderAuth do
alias Assent.Config

@spec request(atom()) :: {:ok, map()} | {:error, term()}
def request(provider) do
  config = config!(provider)

  config[:strategy].authorize_url()
end

@spec callback(atom(), map(), map()) :: {:ok, map()} | {:error, term()}
def callback(provider, params, session_params) do
  config = config!(provider)

  config
  |> Assent.Config.put(:session_params, session_params)
  |> config[:strategy].callback(params)
end

defp config!(provider) do
  config =
    Application.get_env(:my_app, :strategies)[provider] ||
      raise "没有#{provider}的提供者配置"
  
  Config.put(config, :redirect_uri, "http://localhost:4000/oauth/#{provider}/callback")
end
end

自定义提供者

你可以创建自定义策略。以下是使用 Assent.Strategy.OAuth2.Base 实现 OAuth 2.0 的示例:

defmodule TestProvider do
use Assent.Strategy.OAuth2.Base

@impl true
def default_config(_config) do
  [
    # `:base_url` 将用于以下任何路径
    base_url: "http://localhost:4000/api/v1",
     # 定义绝对 URI 会覆盖 `:base_url`
    authorize_url: "http://localhost:4000/oauth/authorize",
    token_url: "/oauth/access_token",
    user_url: "/user",
    authorization_params: [scope: "email profile"],
    auth_method: :client_secret_post
  ]
end

@impl true
def normalize(_config, user) do
  {:ok,
    # 符合 https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.5.1
    %{
      "sub"      => user["sub"],
      "name"     => user["name"],
      "nickname" => user["username"],
      "email"    => user["email"]
    # },
    # # 不属于标准声明规范的提供者特定数据
    # %{
    #   "http://localhost:4000/bio" => user["bio"]
    }
  }
end
end

规范化的用户映射应符合 OpenID Connect Core 1.0 标准声明规范,并应返回 {:ok, userinfo_claims}{:ok, userinfo_claims, additional}。用户信息声明中定义的任何不属于规范的键都不会包含在用户映射中。相反,它们应该设置在附加数据中,然后合并到用户信息声明之上,排除任何已经设置的键。

你可以使用 Assent.Strategy.OAuth2.BaseAssent.Strategy.OAuth.BaseAssent.Strategy.OIDC.Base 宏来设置策略。

如果你需要比宏提供的更多控制权,可以使用 Assent.Strategy 行为来实现你的提供者:

defmodule TestProvider do
  @behaviour Assent.Strategy

  @spec authorize_url(Keyword.t()) :: {:ok, %{url: binary()}} | {:error, term()}
  def authorize_url(config) do
    # 生成授权 URL
  end

  @spec callback(Keyword.t(), map()) :: {:ok, %{user: map(), token: map()}} | {:error, term()}
  def callback(config, params) do
    # 处理回调响应
  end
end

HTTP 客户端

Assent 默认支持 ReqFinch:httpc。如果启用,默认使用 Req HTTP 客户端适配器,否则将包含 Erlang 的 :httpc 适配器。

你可以在配置中显式设置 HTTP 客户端适配器:

config = [
  client_id: "替换为客户端 ID",
  client_secret: "替换为客户端密钥",
  http_adapter: Assent.HTTPAdapter.Httpc
]

或在全局配置中设置:

config :assent, http_adapter: Assent.HTTPAdapter.Httpc

Req

Req 不需要任何额外配置,可以直接使用:

defp deps do
  [
    # ...
    {:req, "~> 0.4"}
  ]
end

:httpc

如果 Req 不可用,将使用 Erlang 内置的 :httpc 进行请求。当 :certifi:ssl_verify_fun 包可用时,会自动启用 SSL 验证。:httpc 仅支持 HTTP/1.1。

defp deps do
  [
    # ...
    # 如果使用 `:httpc` 适配器,需要 SSL 验证
    {:certifi, "~> 2.4"},
    {:ssl_verify_fun, "~> 1.1"}
  ]
end

你必须将 :inets 添加到 :extra_applications 中,以在你的发布版本中包含 :httpc

Finch

Finch 需要在你的应用程序中有一个监督器。

更新 mix.exs

defp deps do
  [
    # ...
    {:finch, "~> 0.16"}
  ]
end

确保在你的应用程序中启动 Finch 监督器,并在提供者配置中使用你的连接池设置 :http_adapter

config = [
  client_id: "替换为客户端 ID",
  client_secret: "替换为客户端密钥",
  http_adapter: {Assent.HTTPAdapter.Finch, supervisor: MyFinch}
]

JWT 适配器

默认使用内置的 Assent.JWTAdapter.AssentJWT 进行 JWT 解析,但你可以使用自定义的 Assent.JWTAdapter 更改为任何第三方库。包含了一个 JOSE 适配器 Assent.JWTAdapter.JOSE

要使用 JOSE,更新 mix.exs

defp deps do
  [
    # ...
    {:jose, "~> 1.8"}
  ]
end

并在提供者配置中传递 :jwt_adapter

config = [
  client_id: "替换为客户端 ID",
  client_secret: "替换为客户端密钥",
  jwt_adapter: Assent.JWTAdapter.JOSE
]

或在全局配置中设置:

config :assent, jwt_adapter: AssAssent.JWTAdapter.JOSE

许可证

(MIT 许可证)

版权所有 (c) 2019-至今 Dan Schultzer 及贡献者

特此免费授予任何获得本软件副本和相关文档文件("软件")的人不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、出版、发布、分发、再许可和/或销售软件副本的权利,以及允许向其提供软件的人这样做,但须符合以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。

软件按"原样"提供,不提供任何形式的明示或暗示担保,包括但不限于对适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为或其他方面,由软件或软件的使用或其他交易引起的或与之相关的。

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

AIWritePaper论文写作

AIWritePaper论文写作是一站式AI论文写作辅助工具,简化了选题、文献检索至论文撰写的整个过程。通过简单设定,平台可快速生成高质量论文大纲和全文,配合图表、参考文献等一应俱全,同时提供开题报告和答辩PPT等增值服务,保障数据安全,有效提升写作效率和论文质量。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号