ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Faraday Authentication 中间件详解:为请求自动添加 Authorization 请求头

Faraday Authentication 中间件详解:为请求自动添加 Authorization 请求头 后端网络通信【免费下载链接】faradaySimple, but flexible HTTP client library, with support for multiple backends.项目地址https://gitcode.com/gh_mirrors/fa/faraday点击查看免费下载导读Faraday::Request::Authorization是 Faraday 内置的请求中间件request middleware其核心职责是在请求真正发往 Adapter 之前自动为每一个请求注入Authorization请求头并提供开箱即用的 Basic AuthenticationBasic 认证辅助能力。通过本文你将掌握如何在 Faraday 2.x 中使用conn.request :authorization配置 Bearer Token、自定义认证头、以及由 Proc / 可调用对象驱动的动态凭证方案同时了解 Basic 认证的底层 Base64 编码原理与 1.x 到 2.x 的迁移差异。中间件在请求链路中的位置在 Faraday 中中间件以 Rack 风格堆叠在请求/响应链路上参见 中间件总览。请求中间件request middleware在 Adapter 执行 HTTP 请求之前运行通常用于设置请求头或转换请求体。Authorization中间件即属于此类它在on_request阶段被调用将认证头写入env.request_headers随后才将请求交给下游直至最内层的 Adapter。这一位置的确认可直接从源码得到lib/faraday/middleware.rb#L54-L58Middleware#call先调用on_request(env)再调用app.call(env)向下传递lib/faraday/request/authorization.rb#L22-L27中间件的on_request中完成Authorization头的设置。因此只要把conn.request :authorization, ...加入连接构建块该连接发出的每个请求都会自动携带认证头无需在每次调用conn.get/conn.post时手动传入 header。基本用法静态凭证自定义认证类型如 Bearer Token最常见的用法是指定认证类型type与一个静态值例如 Bearer TokenFaraday.new(...) do |conn| conn.request :authorization, Bearer, authentication-token end该配置最终会在每次请求时生成请求头Authorization: Bearer authentication-tokentype既可以是字符串也可以是 Symbol。中间件在拼接头时不做大小写归一化Bearer会原样输出见 lib/faraday/request/authorization.rb#L47 中的#{type} #{value}。参数约束从源码 lib/faraday/request/authorization.rb#L35-L49 可以看出除 Basic 类型外中间件要求恰好一个value 参数传入params.size ! 1时例如conn.request :authorization, Bearer, foo, bar会抛出ArgumentError对应的测试用例见 spec/faraday/request/authorization_spec.rb#L110-L116when passed too many arguments期望raise_error(ArgumentError)。这一约束意味着如果你的认证方案需要多个字段如 OAuth 的多参数形式应在 Proc 中自行拼接或采用其他中间件方案。动态凭证使用 Proc 与可调用对象无参数 Proc凭证可能随时间变化例如从配置中心、内存缓存读取 Token此时可传入一个 Proc它会在每次请求时被求值Faraday.new(...) do |conn| conn.request :authorization, Bearer, - { MyAuthStorage.get_auth_token } end带env参数的 Proc如果 Proc 声明了一个参数中间件会把转发下来的env即Faraday::Env对象传给它。这样动态凭证可以感知当前请求的上下文例如根据请求头中的某个字段决定 TokenFaraday.new(...) do |conn| conn.request :authorization, Bearer, -(env) { MyAuthStorage.get_auth_token(env) } end关于env对象上可用的属性:method、:url、:request_headers、:request_body、:params等可参考 Env 对象说明。其中:request_headers是Faraday::Utils::Headers类型可在 Proc 内读取其他已设置的请求头。底层分派逻辑源码 lib/faraday/request/authorization.rb#L41-L47 实现了精确的调用约定if (value.is_a?(Proc) value.arity 1) || (value.respond_to?(:call) value.method(:call).arity 1) value value.call(env) elsif value.is_a?(Proc) || value.respond_to?(:call) value value.call end #{type} #{value}即若值是 Proc或任意响应#call的对象且元数为 1则调用value.call(env)把env传入若值是 Proc 或可调用对象但元数为 0则直接value.call否则当作静态值直接拼接。这意味着除了 lambda / proc任何实现了#call方法的对象如自定义的Authorizer类实例都能作为动态凭证源。测试 spec/faraday/request/authorization_spec.rb#L58-L107 覆盖了 proc、lambda、双参数 callable、带参数的 callable 等多种形态并验证了它们生成的头值。Basic Authentication自动 Base64 编码Basic 认证是 HTTP 标准认证方式将username:password拼接后做 Base64 编码再以Basic前缀写入Authorization头。该中间件封装了完整的编码过程你只需提供明文用户名与密码Faraday.new(...) do |conn| conn.request :authorization, :basic, username, password end以username/password为例生成的头为Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQdXNlcm5hbWU6cGFzc3dvcmQ正是字符串username:password的 Base64 编码结果。编码实现Basic 编码并非在中间件内联实现而是由Faraday::Utils.basic_header_from完成见 lib/faraday/utils.rb#L55-L59def basic_header_from(login, pass) value [#{login}:#{pass}].pack(m) # Base64 encoding value.delete!(\n) Basic #{value} end注意两点实现细节使用 Ruby 内置Array#pack(m)做 Base64 编码随后删除换行符pack(m)默认会在每 60 个字符后插入换行中间件通过type.to_s.casecmp(basic).zero? params.size 2识别 Basic 模式见 lib/faraday/request/authorization.rb#L36因此:basic与Basic、BASIC等大小写变体均可生效。测试验证spec/faraday/request/authorization_spec.rb#L27-L45 对 Basic 认证做了充分验证aladdin/opensesame生成Basic YWxhZGRpbjpvcGVuc2VzYW1l超长值255 个A加空密码生成Basic QUFB...Og验证了编码对长输入的正确性。需要提醒的是Basic 认证的 Base64 编码不是加密明文可轻易解码务必只在 HTTPS 连接下使用避免凭证在传输中被窃取。已有 Authorization 头不会被覆盖中间件具备幂等保护如果请求已经携带了Authorization头中间件会直接跳过不会覆盖调用方显式传入的认证信息。源码 lib/faraday/request/authorization.rb#L23-L27def on_request(env) return if env.request_headers[KEY] env.request_headers[KEY] header_from(type, env, *params) end测试 spec/faraday/request/authorization_spec.rb#L15-L23 中的共享示例does not interfere with existing authentication验证了该行为当conn.get(/auth-echo, nil, authorization: OAuth oauth_token)显式传入认证头时响应中回显的仍是OAuth oauth_token而非中间件生成的值。这意味着你可以在连接级配置一个默认认证方案同时在个别请求中通过headers参数临时覆盖例如使用临时 OAuth Token 或切换账号。与 Faraday 1.x 的用法差异Faraday 1.x 与 2.x 的用法不同。在 1.x 中认证中间件暴露为三个快捷方法而在 2.x 中统一收敛为conn.request :authorization。以下 1.x 写法仅供参考迁移当前仓库版本为 Faraday 2.x见 lib/faraday/version.rbVERSION 2.14.3# 1.xBasic Auth 请求 # 生成头Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ Faraday.new(...) do |conn| conn.request :basic_auth, username, password end # 1.xToken Auth 请求 # options 会自动转换为 keyvalue 格式 # 生成头Authorization: Token authentication-token options Faraday.new(...) do |conn| conn.request :token_auth, authentication-token, **options end # 1.x通用 Auth 请求 # 生成头Authorization: Bearer authentication-token Faraday.new(...) do |conn| conn.request :authorization, Bearer, authentication-token end迁移建议在 2.x 中conn.request :authorization, type, value已覆盖 1.x 的三个快捷入口1.x 写法2.x 等价写法conn.request :basic_auth, user, passconn.request :authorization, :basic, user, passconn.request :token_auth, token, **optsconn.request :authorization, Token, -(env) { build_token(env, opts) }conn.request :authorization, Bearer, tokenconn.request :authorization, Bearer, token保持不变1.x 的token_auth会把options自动转换为keyvalue片段如Token token kv。2.x 中该行为不再自动发生若仍需生成类似格式可在 Proc 中自行拼接字符串。注意2.x 中params.size ! 1非 Basic 模式会直接抛出ArgumentError因此token_auth式的多参数写法不能原样照搬。注册机制与其他入口Authorization中间件通过以下语句注册到Faraday::Request命名空间lib/faraday/request/authorization.rb#L54Faraday::Request.register_middleware(authorization: Faraday::Request::Authorization)因此你可以通过conn.request :authorization, ...使用它。除了符号快捷方式也可直接用类名添加两种方式等价参见 中间件总览Faraday.new(...) do |conn| conn.use Faraday::Request::Authorization, Bearer, authentication-token end此外连接级还有一个与认证相关的内置能力Faraday::Connection#set_basic_authlib/faraday/connection.rb#L379-L382。当 URL 中内嵌了user:passwordhost形式的凭证时连接初始化阶段会通过set_basic_auth直接写入 Basic 认证头见 lib/faraday/connection.rb#L371-L374其内部同样复用Faraday::Utils.basic_header_from。这与Authorization中间件是两条独立的设置路径但最终都作用在同一个Authorization请求头上。一个完整的实战示例综合以上能力下面是一个完整的连接配置同时演示静态 Bearer、动态凭证与 Basic 认证三种形态require faraday # 静态 Bearer Token conn Faraday.new(url: https://api.example.com) do |c| c.request :authorization, Bearer, static-token c.adapter :net_http end conn.get(/users) # Authorization: Bearer static-token # 动态凭证每次请求重新求值 conn2 Faraday.new(url: https://api.example.com) do |c| c.request :authorization, Bearer, - { TokenStore.current_token } c.adapter :net_http end conn2.get(/users) # Authorization: Bearer TokenStore.current_token 当前值 # 基于请求上下文的动态凭证 conn3 Faraday.new(url: https://api.example.com) do |c| c.request :authorization, Bearer, -(env) { TokenStore.token_for(env.url) } c.adapter :net_http end # Basic 认证自动 Base64 编码 conn4 Faraday.new(url: https://api.example.com) do |c| c.request :authorization, :basic, username, password c.adapter :net_http end conn4.get(/basic) # Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ小结Faraday::Request::Authorization是 Faraday 2.x 内置的请求中间件负责在请求发出前自动设置Authorization头支持静态值、无参 Proc、带env参数的 Proc以及任意响应#call的对象按元数自动分派:basic模式自动完成 Base64 编码编码逻辑位于 lib/faraday/utils.rb#L55-L59已有Authorization头不会被中间件覆盖可在请求级显式覆盖默认认证非 Basic 模式只接受恰好一个 value 参数多余参数抛出ArgumentErrorFaraday 1.x 的basic_auth/token_auth快捷方式在 2.x 已收敛为统一的conn.request :authorization迁移时注意token_auth的多参数行为差异。相关源码与测试可进一步阅读中间件实现、中间件测试、中间件基类、中间件总览文档。赞分享后端网络通信【免费下载链接】faradaySimple, but flexible HTTP client library, with support for multiple backends.项目地址https://gitcode.com/gh_mirrors/fa/faraday点击查看免费下载相关推荐LanceDB Node.js SDK 的 HeaderProvider 详解为远程请求注入动态请求头LanceDB Node.js SDK 的 HeaderProvider 详解为远程请求注入动态请求头 导读 HeaderProvider 是 LanceDB数据库向量数据库全文检索人工智能vercel/functions 的 next() 函数详解在 Vercel 中间件中放行请求、透传响应头与请求头vercel/functions 的 next 函数详解在 Vercel 中间件中放行请求、透传响应头与请求头 next 是 Vercel 运行时函数库 CLI后端云原生SPlayer中的HTTP请求拦截统一错误处理与请求头添加实现SPlayer中的HTTP请求拦截统一错误处理与请求头添加实现 你是否曾遇到音乐播放器加载失败、登录状态丢失或网络请求频繁出错的问题在SPlayer中这些音视频桌面应用前端上一篇DLSS Swapper终极指南一键管理游戏DLSS文件释放NVIDIA显卡全部性能下一篇3步完成碧蓝航线全自动托管Alas智能助手终极使用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表