多提供商认证框架。
Assent.Strategy.OAuthAssent.Strategy.OAuth2Assent.Strategy.OIDCAssent.Strategy.AppleAssent.Strategy.Auth0Assent.Strategy.AzureADAssent.Strategy.BasecampAssent.Strategy.DigitalOceanAssent.Strategy.DiscordAssent.Strategy.FacebookAssent.Strategy.GithubAssent.Strategy.GitlabAssent.Strategy.GoogleAssent.Strategy.InstagramAssent.Strategy.LINEAssent.Strategy.LinkedinAssent.Strategy.SpotifyAssent.Strategy.StravaAssent.Strategy.SlackAssent.Strategy.StripeAssent.Strategy.TwitterAssent.Strategy.VK在 mix.exs 中将 Assent 添加到依赖 列表:
defp deps do [ # ... {:assent, "~> 0.2.9"} ] end
运行 mix deps.get 进行安装。
默认情况下,如果您的依赖列表中有 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 适配器(如 Req 或 Finch),则无需进行此操作。
策略包含两个阶段:请求和回调。在请求阶段,通常会将用户重定向到提供商进行认证,然后返回以启动回调阶段。
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.Base、Assent.Strategy.OAuth.Base 和 Assent.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
Assent 默认支持 Req、Finch 和 :httpc。如果启用,默认使用 Req HTTP 客户端适配器,否则将包含 Erlang 的 :httpc 适配器。
你可以在配置中显式设置 HTTP 客户端适配器:
config = [ client_id: "替换为客户端 ID", client_secret: "替换为客户端密钥", http_adapter: Assent.HTTPAdapter.Httpc ]
或在全局配置中设置:
config :assent, http_adapter: Assent.HTTPAdapter.Httpc
ReqReq 不需要任何额外配置,可以直接使用:
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 需要在你的应用程序中有一个监督器。
更新 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} ]
默认使用内置的 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 及贡献者
特此免费授予任何获得本软件副本和相关文档文件("软件")的人不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、出版、发布、分发、再许可和/或销售软件副本的权利,以及允许向其提供软件的人这样做,但须符合以下条件:
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按"原样"提供,不提供任何形式的明示或暗示担保,包括但不限于对适销性、特定用途适用性和非侵权性的担保。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任负责,无论是在合同诉讼、侵权行为或其他方面,由软件或软件的使用或其他交易引起的或与之相关的。


AI赋能电商视觉革命,一站式智能商拍平台
潮际好麦深耕服装行业,是国内AI试衣效果最好的软件。使用先进AIGC能力为电商卖家批量提供优质的、低成本的商拍图。合作品牌有Shein、Lazada、安踏、百丽等65个国内外头部品牌,以及国内10万+淘宝、天猫、京东等主流平台的品牌商家,为卖家节省将近85%的出图成本,提升约3倍出图效率,让品牌能够快速上架。


企业专属的AI法律顾问
iTerms是法大大集团旗下法律子品牌,基于最先进的大语言模型(LLM)、专业的法律知识库和强大的智能体架构,帮助企业扫清合规障碍,筑牢风控防线,成为您企业专属的AI法律顾问。


稳定高效的流量提升解决方案,助力品牌曝光
稳定高效的流量提升解决方案,助力品牌曝光


最新版Sora2模型免费使用,一键生成无水印视频
最新版Sora2模型免费使用,一键生成无水印视频


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


选题、配图、成文,一站式创作,让内容运营更高效
讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。


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


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


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


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

微信扫一扫关注公众号