Rspec:如何让Omniauth/Auth0与Faraday请求配合实现认证?
针对你的问题,我有两个实用解决方案:一个是调整现有Graphlient+Faraday配置,同步认证Cookie;另一个是更高效的直接测试GraphQL Schema的方案,彻底绕开HTTP层面的认证问题。
解决方案一:同步Capybara认证Cookie到Graphlient的Faraday请求
你通过sign_in方法用Capybara完成认证后,认证Cookie保存在Capybara的会话里,但Graphlient的Faraday连接是独立的,所以需要手动把这些Cookie同步到Faraday的请求头中。修改你的GraphQL Client共享上下文即可:
require 'graphlient' RSpec.shared_context "GraphQL Client", shared_context: :metadata do let(:client) do # 从Capybara当前会话提取所有认证Cookie auth_cookies = Capybara.current_session.driver.request.cookies # 格式化为HTTP标准的Cookie头字符串 cookie_header = auth_cookies.map { |name, value| "#{name}=#{value}" }.join('; ') Graphlient::Client.new('https://www.example.org/graphql') do |client| client.http do |h| h.connection do |c| # 添加上Cookie请求头 c.headers['Cookie'] = cookie_header c.use Faraday::Adapter::Rack, app end end end end end
这样配置后,Graphlient发起的所有GraphQL请求都会带上和Capybara会话一致的认证Cookie,就能通过Auth0的认证校验了。
解决方案二:直接测试GraphQL Schema(更优方案)
如果你的测试目标是验证自己的GraphQL API逻辑,完全不需要走HTTP请求流程,直接调用Rails的GraphQL Schema执行查询会更高效,还能彻底避开Cookie认证的问题。
假设你的应用定义了MyAppSchema(具体名称根据你的项目调整),可以这样写测试:
RSpec.describe "User Profile Query", type: :request do let(:test_user) { create(:user) } # 用FactoryBot创建测试用户 it "returns the correct user profile data" do # 定义GraphQL查询 profile_query = <<~GRAPHQL query GetUser($userId: ID!) { user(id: $userId) { id name email } } GRAPHQL # 直接调用Schema执行查询,手动设置上下文里的当前用户 result = MyAppSchema.execute( profile_query, variables: { userId: test_user.id }, context: { current_user: test_user } ) # 断言返回结果 expect(result["data"]["user"]["email"]).to eq(test_user.email) expect(result["errors"]).to be_nil end end
这种方法的优势很明显:
- 速度更快:跳过HTTP服务器和网络请求,测试执行效率大幅提升
- 逻辑更清晰:直接控制GraphQL上下文,不需要依赖Omniauth的认证流程,测试用例更独立
- 调试更方便:可以直接打印
result查看数据或错误信息,定位问题更快捷
如果你的GraphQL resolver依赖current_user(通常从请求会话或头信息获取),只需要在测试时把用户实例直接传入context,就能和生产环境的逻辑对齐。
内容的提问来源于stack exchange,提问作者madav
相关产品推荐
相关产品推荐

