【问题标题】:GraphQL/ Rails 422 Unprocessable Entity - Saving token to SessionGraphQL/ Rails 422 无法处理的实体 - 将令牌保存到会话
【发布时间】:2019-06-14 08:20:00
【问题描述】:

我目前正在努力将项目的 rails 后端从 REST 更改为 graphql,我在按照他们的教程进行身份验证时遇到了错误 - https://www.howtographql.com/graphql-ruby/4-authentication/

我正在使用 GraphiQL 引擎测试我的所有请求并收到错误 status 422 unprocessable Entity, User Must Exist

这是有道理的,因为我正在执行的突变是创建一种新颜色 - 它与用户具有 belongs_to 关系。

链接到above ^^^ 的页面大约在一半的时候是这样写的:

使用signinUser 突变提供的令牌,应用程序可以 验证后续请求。有几种方法可以 完成。在本教程中,我们将只使用内置的 session,因为这不会向客户端应用程序添加任何要求。 GraphQL 服务器应该能够从 每个请求的会话标头,检测它与哪个用户相关, 并将此信息传递给解析器。

我能够通过 signinUser 方法成功返回身份验证令牌,就像之前在同一页面上显示的文档一样 - 它发布的方法还将令牌保存到这个假定的 会话在此方法中(也来自上面发布的同一链接^^^):

def call(_obj, args, ctx)
    input = args[:email]

    return unless input

    user = User.find_by email: input[:email]

    return unless user
    return unless user.authenticate(input[:password_digest])

    crypt = ActiveSupport::MessageEncryptor.new(ENV["SECRET_BASE_KEY"])

    token = crypt.encrypt_and_sign("user-id:#{ user.id }")

    puts "please **********************************"
    p ctx[:session]


    ctx[:session][:token] = token

    puts "please **********************************"
    p ctx[:session]

    OpenStruct.new({
      user: user,
      token: token
      })
  end

您将能够在我的拼命挣扎中看到,我在方法返回之前删除了会话,并且毫不奇怪地看到它包含用户登录的令牌。

但是,当我继续执行突变以创建颜色时,我的期望是会话仍将包含该标记,并且我能够成功提交该颜色。情况并非如此,当我为这个请求删除会话时,它返回一个空哈希。

我找不到有关内置 graphql session 工作原理的任何信息 - 而且我对 graphql 总体来说是全新的。


我的主要问题是 - graphql session 是否应该缓存令牌信息?为什么信息没有传递给signinUser 之后的请求?由于文档声称这种身份验证方法不是长期解决方案,我是否应该尝试在本教程中使用身份验证?


我知道这很多,但真的很感激在这方面多花点心思。

提前致谢!

附言。我了解本教程使用 links 并且我在此处使用 colors - 这是故意的,我已尽力确保语义差异不会导致任何错误。 p>

  • Rails 版本 - 5.2.2(仅使用 api)

  • graphql - 1.7.4

  • graphiql rails - 1.4.4

【问题讨论】:

    标签: ruby-on-rails ruby graphql graphiql http-status-code-422


    【解决方案1】:

    与 REST API 相同,GraphQL 不会在两个后续请求之间存储任何信息,您必须将登录突变返回的身份验证令牌传递给您想要当前用户相关信息的所有后续请求。

    您应该在graphql_controller.rb 中执行以下操作

    class GraphqlController < ApplicationController
      def execute
        variables = ensure_hash(params[:variables])
        query = params[:query]
        operation_name = params[:operationName]
        context = {
          current_user: current_user
        }
        result = GraphqlTutorialSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
    
        render json: result
      end
    
      private
    
      # set current user here
      def current_user
        # you can token here
        token = request.headers['Authorization']
        return nil unless token
        # find current user from this token
      end
    
      # Handle form data, JSON body, or a blank value
      def ensure_hash(ambiguous_param)
        # ...code
      end
    end
    

    【讨论】:

      【解决方案2】:

      我的一位同事指出,“会话”是 rails 的一部分,应该创建一个可从下一个请求访问的 cookie。

      我提到我使用的是 Rails 版本 - 5.2.2(仅使用 api) - 当您在初始化新的 rails 项目时使用 -api 标志时,它会将这些行添加到 application.rb

      # Settings in config/environments/* take precedence over those specified here.
      # Application configuration can go into files in config/initializers
      # -- all .rb files in that directory are automatically loaded after loading
      # the framework and any gems in your application.
      
      # Only loads a smaller set of middleware suitable for API only apps.
      # Middleware like session, flash, cookies can be added back manually.
      # Skip views, helpers and assets when generating a new resource.
      config.api_only = true
      

      特别注意这一行 - Middleware like session, flash, cookies can be added back manually.


      我注释掉了config.api_only = true,这会将 cookie 添加回应用程序/允许我向现有用户发出下一个请求。

      如果您不想删除仅限 api 的功能,您还可以添加我从“Lysender”的帖子中找到的这些行 - Rails 5 – API Only – Enable Cookies and Sessions

      config.api_only = true
      config.middleware.use ActionDispatch::Cookies
      config.middleware.use ActionDispatch::Session::CookieStore, key: '_coookie_name', expire_after: 30.days
      

      【讨论】:

        猜你喜欢
        • 2016-01-13
        • 2016-10-30
        • 1970-01-01
        • 2021-03-19
        • 2021-05-27
        • 1970-01-01
        • 1970-01-01
        • 2019-07-11
        • 2014-12-24
        相关资源
        最近更新 更多