Faraday: 警告:不推荐使用`Faraday::Connection#basic_auth`

创建于 2021-08-31  ·  9评论  ·  资料来源: lostisland/faraday

基础信息

  • 法拉第版本: 1.7.1
  • 红宝石版本: 3.0.2

问题描述

看到了弃用警告,更新了代码以匹配记录的基本身份验证说明。 记录的代码引发了许多参数错误。

不确定文档是错误的还是 gem 的问题。

重现步骤

http = Faraday.new do |conn|
  conn.request(:authorization, :basic, 'username', 'password')
end

http.post("https://example.com")
ArgumentError: wrong number of arguments (given 4, expected 3)
from /Users/mscoutermarsh/.rbenv/versions/3.0.2/lib/ruby/gems/3.0.0/gems/faraday-1.7.1/lib/faraday/request/authorization.rb:43:in `initialize'

所有9条评论

文档是错误的 :) 我刚刚打开了一个 PR 来解决这个问题。

同时,您需要像这样使用它:

http = Faraday.new do |conn|
  conn.request(:basic_auth, 'username', 'password')
end

你好! 不与 1.x 弃用消息押韵的文档网站的上下文是:“所有网站文档都是即将到来的 2.0”。 删除旧方式的那个版本。

上下文仅在自述文件中提及 - 这是一个弱点,我们希望在网站前端获得具体帮助。

链接到该部分:

https://github.com/lostisland/faraday#attention

@peterberkenbosch是正确的,这是在 Faraday 1.x 中使用中间件的正确方法,而文档显示了即将推出的 v2.0 的正确用法。

很抱歉造成混乱,这不是第一次提出这样的问题。 我会寻找一个快速的解决方案,让事情更清楚

谢谢! 现在一切都很好。 ❤️

你好@iMacTia

我在这个问题上仍然有问题。
我使用的是法拉第 1.7.1 和 Ruby 2.7.2。

我最初创建了这样的连接

client = Faraday.new(url: url) do |faraday|
    faraday.headers["Accept"] = "application/json"
    faraday.headers["X-Version"] = "2"
    faraday.headers["Authorization"] = "token #{token}"
    faraday.request(:json)
    faraday.response(:json, content_type: /\bjson$/)
    faraday.adapter(Faraday.default_adapter)
  end

基于上面的讨论,我想如果我切换到使用 faraday.request(:token_auth, token),它应该有助于在请求中添加标头,所以我切换到

client = Faraday.new(url: url) do |faraday|
    faraday.headers["Accept"] = "application/json"
    faraday.headers["X-Version"] = "2"
    faraday.request(:token_auth, token)
    faraday.request(:json)
    faraday.response(:json, content_type: /\bjson$/)
    faraday.adapter(Faraday.default_adapter)
end

上面的客户端就是这样使用的,我得到了错误"errors"=>["Authentication Required"]

client.get(path, {"sort"=>"created_at", "direction"=>"desc", "per_page"=>100})

我还调试了代码,不知何故,中间件没有在请求中生效并且标头中没有Authorization ,这是一个请求对象转储

#<struct Faraday::Request http_method=:get, path="hide/the/path", params={"sort"=>"created_at", "direction"=>"desc", "per_page"=>100}, headers={"Accept"=>"application/json;", "X-Version"=>"2", "User-Agent"=>"Faraday v1.7.1"}, body=nil, options=#<Faraday::RequestOptions (empty)>>

我是否以错误的方式使用它还是应该创建一个新的错误?

顺便说一句, faraday.headers["Authorization"] = "token #{token}"faraday.request(:token_auth, token)之间有什么区别。 根据我的新手 ruby​​ 知识和阅读源代码, token_auth正在尝试设置标头,相当于faraday.headers[]= 。 那么在doc中,为什么我们建议使用中间件而不是直接设置header呢?

@xiaoxipang ,里面有很多好问题,让我看看我是否能全部回答。

我是否以错误的方式使用它还是应该创建一个新的错误?

您正确使用了它,但我怀疑中间件的输出并不完全符合服务器的预期。
这种“令牌身份验证”看起来像是一个非常旧的标准,不再使用,并已被不记名令牌和其他机制取代。 您示例中的标头输出将是Authorization: Token token=token ,请注意token=前缀,我怀疑您的服务器没有预料到。 要解决此问题,您可以改为执行以下操作:

client = Faraday.new(url: url) do |faraday|
    # This header is not necessary, it will be set by the json middleware
    # faraday.headers["Accept"] = "application/json"
    faraday.headers["X-Version"] = "2"
    faraday.request(:authorization, 'Token', token)
    faraday.request(:json)
    faraday.response(:json, content_type: /\bjson$/)
    faraday.adapter(Faraday.default_adapter)
end

这会将标头正确设置为Authorization: Token token (无前缀)。
请试一试,让我知道它是否有效!

我还调试了代码,不知何故,中间件没有在请求中生效,头部没有授权,这是一个请求对象转储

这很奇怪,我刚刚测试了上面的代码,它按我的预期工作。 在调试中看到struct Faraday::Request我怀疑您可能在中间件设置标头之前过早地查看对象。
如果您运行一个请求并检查响应,您一定会在那里看到它:

client.get('https://google.co.uk')
 => #<Faraday::Response:0x00007fdd01ad1340
  @on_complete_callbacks=[],
  @env=#<Faraday::Env
    @method=:get
    @url=#<URI::HTTPS https://google.co.uk/>
    @request=#<Faraday::RequestOptions (empty)>
    @request_headers={"X-Version"=>"2", "User-Agent"=>"Faraday v1.7.1", "Authorization"=>"Token token"}
    ...

或者另一种方法是在您的适配器之前添加faraday.response :logger中间件,这样它就会在所有中间件生效后记录请求,您一定会看到它。

顺便说一句, faraday.headers["Authorization"] = "token #{token}" 和 faraday.request(:token_auth, token) 有什么区别。 根据我的新手ruby知识和阅读源代码,token_auth正在尝试设置header,相当于faraday.headers[]=。 那么在doc中,为什么我们建议使用中间件而不是直接设置header呢?

该建议的主要原因是中间件通常提供更多的功能。
例如, token_auth中间件也允许您设置令牌属性并自动格式化它们:

faraday.request(:token_auth, 'token', {prop1: value1, prop2: value2})
# This produces `Authorization: Token token=token prop1=value1 prop2=value2

以类似的方式, basic_auth中间件会自动对您的用户/密码对进行 Base64 编码。

我同意上面的faraday.request(:authorization, 'Token', token)中间件除了手动设置标头之外并没有做更多的事情,但是例如在 Faraday v2 中,中间件接受token参数的 lambda/proc 并自动解决每个要求。 这允许您拥有一个TokenStorage类并在不同请求之间动态更改令牌。 使用另一种方法,您需要在每个请求上手动注入标头或每次都重新创建连接。

我希望这能回答你的问题,但简而言之,你可以同时使用这两种方法,所以请使用你最喜欢的一种 😄

@iMacTia 非常感谢您的帮助和详细解释!

请试一试,让我知道它是否有效!

faraday.request(:authorization, "token", token)对我有用。

或者另一种方法是在你的适配器之前添加 faraday.response :logger 中间件,这样它就会记录
在所有中间件生效后请求,您一定会看到它。

从现在开始知道如何调试真是太好了。 通过使用它,你是完全正确的:
使用faraday.request(:authorization, "token", token) ,标题为Authorization: "token token_value"
使用faraday.request(:token_auth, token) ,标题为Authorization: "Token token=\"token_value\""

这很奇怪,我刚刚测试了上面的代码,它按我的预期工作。 在调试中看到结构 Faraday::Request 我怀疑您可能在中间件设置标头之前过早地查看对象。

是的,我在connection#run_request放置了断点,此时中间件还没有被调用。 我在 Faraday::Request::Authorization 中添加了一个新的断点,现在我可以看到它是如何工作的。

我希望这能回答您的问题,但总而言之,您可以同时使用这两种方法,因此请使用您最喜欢的一种

是的,再次感谢您!

现在如何摆脱弃用警告?

      builder.request :basic_auth, <strong i="6">@client_id</strong>, <strong i="7">@client_secret</strong>

仍然在 1.7.1 上为我提出警告,正如@mscoutermarsh 所提到的,新语法尚不可用。

@paukul

http = Faraday.new do |conn|
  conn.request(:basic_auth, 'username', 'password')
end

为我们修好了。 看起来和你的一样,不知道为什么它仍然给你警告。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

ioquatix picture ioquatix  ·  4评论

ryanbyon picture ryanbyon  ·  3评论

mokolabs picture mokolabs  ·  3评论

JasonBarnabe picture JasonBarnabe  ·  4评论

jedeleh picture jedeleh  ·  3评论