Rails + Graphql и Аутентификация путаницы - PullRequest
0 голосов
/ 21 октября 2018

Я немного запутался в настройке current_user с GraphQL.Таким образом, способ, которым я сделал бы это в приложении Restful, состоял бы в том, чтобы пользовательский контроллер регистрировал пользователя при его создании следующим образом:

  def create
    @user = User.new(user_params)

    if @user.save
      login(@user)
      render :show
    else
      render json: @user.errors.messages, status: 422
    end
  end

У меня есть метод login (user) внутри контроллера приложения иЧто он делает, он в основном устанавливает для пользователя значение current_user helper_method и назначает маркер сеанса следующим образом:

  protect_from_forgery with: :exception

  helper_method :current_user

  def login(user)
    @current_user = user
    session[:session_token] = user.reset_session_token!
  end

  def logout
    current_user.reset_session_token!
    session[:session_token] = nil
  end

  def logged_in?
    !!current_user
  end

  def current_user
    @current_user ||= User.find_by(session_token: session[:session_token])
  end

Я предполагаю, что мой реальный вопрос заключается в том, как мне сделать так, чтобы current_user присутствовал в контексте моего контроллера GraphQL?Я использую gem 'graphql', который создал контроллер GraphQL для меня, но все еще не понял, как мне его реализовать.Когда новый пользователь создается, его вывод будет

[["username", "elyy"], ["email", "kelly@kelly.com"], ["password_digest", "$2a$10$ATfHgklNx0bED7N9JCQfHuHjNF/sJ5AcwkOzMOqX7sPLdgAREcHd6"], ["created_at", "2018-10-21 01:46:06.913393"], ["updated_at", "2018-10-21 01:46:06.913393"], ["session_token","uOqgAxb5sOLm2AQMExLwaQ"]]

. Для получения дополнительной информации о том, как у меня есть настройки моего проекта, я включу модель User, мутацию для создания пользователя и контроллер GraphQL внизу.,Если вам нужна дополнительная информация, пожалуйста, не стесняйтесь спрашивать.Спасибо за всех, кто поможет объяснить, как я должен подходить к этой проблеме, и дополнительно обучить меня GraphQL, так как я растерялся, когда смотрю на документы и примеры нескольких человек.

Модель пользователя

class User < ApplicationRecord
  has_secure_password

  validates :username, :email, :password_digest, presence: true, on: :create
  validates :username, uniqueness: true
  validates :password, length: { minimum: 6, allow_nil: true }
  validates_format_of :email, :with => /@/

  attr_reader :password

  after_initialize :ensure_session_token

  def self.find_by_credentials(email, password)
    user = User.find_by(email: email)
    user && user.is_password?(password) ? user : nil
  end

  def self.generate_session_token
    SecureRandom.urlsafe_base64
  end

  def password=(password)
    @password = password
    self.password_digest = BCrypt::Password.create(password)
  end

  def is_password?(password)
    BCrypt::Password.new(self.password_digest).is_password?(password)
  end

  def reset_session_token!
    self.session_token = User.generate_session_token
    self.save!
    self.session_token
  end

  def ensure_session_token
    self.session_token ||= User.generate_session_token
  end
end

Создание пользовательской мутации

class Resolvers::CreateUser < GraphQL::Function
  argument :email, !types.String
  argument :password, !types.String
  argument :username, !types.String

  type Types::UserType

  def call(_obj, args, _ctx)
    User.create!(
      email: args[:email],
      password: args[:password],
      username: args[:username]
    )
  end
end

Контроллер GraphQL

class GraphqlController < ApplicationController
  def execute
    variables = ensure_hash(params[:variables])
    query = params[:query]
    operation_name = params[:operationName]
    context = {
      # Query context goes here, for example:
      current_user: current_user,
    }
    result = PrivateBookSchema.execute(query, variables: variables, context: context, operation_name: operation_name)
    render json: result
  rescue => e
    raise e unless Rails.env.development?
    handle_error_in_development e
  end

  private

  # Handle form data, JSON body, or a blank value
  def ensure_hash(ambiguous_param)
    case ambiguous_param
    when String
      if ambiguous_param.present?
        ensure_hash(JSON.parse(ambiguous_param))
      else
        {}
      end
    when Hash, ActionController::Parameters
      ambiguous_param
    when nil
      {}
    else
      raise ArgumentError, "Unexpected parameter: #{ambiguous_param}"
    end
  end

  def handle_error_in_development(e)
    logger.error e.message
    logger.error e.backtrace.join("\n")

    render json: { error: { message: e.message, backtrace: e.backtrace }, data: {} }, status: 500
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...