assent

assent

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

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

Assent身份认证OAuth多服务商ElixirGithub开源项目

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 及贡献者

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

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

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

编辑推荐精选

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
商汤小浣熊

商汤小浣熊

最强AI数据分析助手

小浣熊家族Raccoon,您的AI智能助手,致力于通过先进的人工智能技术,为用户提供高效、便捷的智能服务。无论是日常咨询还是专业问题解答,小浣熊都能以快速、准确的响应满足您的需求,让您的生活更加智能便捷。

imini AI

imini AI

像人一样思考的AI智能体

imini 是一款超级AI智能体,能根据人类指令,自主思考、自主完成、并且交付结果的AI智能体。

Keevx

Keevx

AI数字人视频创作平台

Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。

即梦AI

即梦AI

一站式AI创作平台

提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作

扣子-AI办公

扣子-AI办公

AI办公助手,复杂任务高效处理

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI辅助写作AI工具蛙蛙写作AI写作工具学术助手办公助手营销助手AI助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
下拉加载更多