Разработать проблему с set_user_by_token

У меня возникла простая проблема, и я не могу найти способ ее исправить, хотя я и нашел, где она.

То, что я пытаюсь сделать, это настроить сброс пароля устройства с помощью devise_token_auth. У меня есть электронная почта с генератором токенов и ссылки на конечные точки '/api/auth/passwords/edit' который проверяет токен, а затем перенаправляет его в мою форму сброса пароля переднего плана (если это имеет значение, реагирует на реакцию), проблема возникает, когда я фактически отправляю форму, я отправляю токен, я также отправляю пароль и подтверждение, expiry, uid и все остальные заголовки.

Так вот в чем проблема, контроллер devise passwords вызывает предварительное действие set_user_by_token, и я обнаружил, что в этом-то и заключается отладка, я создал и переопределил модуль с кодом по умолчанию для set_users_by_token, а также с помощью binding.pry Я видел, что через вызов метода не поступало никаких значений, но метод вызывался, потому что он достиг цели.

вот код метода

  def set_user_by_token(mapping=nil)
    # determine target authentication class
    rc = resource_class(mapping)

    # no default user defined
    return unless rc

    # gets the headers names, which was set in the initialize file
    uid_name = DeviseTokenAuth.headers_names[:'uid']
    access_token_name = DeviseTokenAuth.headers_names[:'access-token']
    client_name = DeviseTokenAuth.headers_names[:'client']

    # parse header for values necessary for authentication
    uid        = request.headers[uid_name] || params[uid_name]
    @token     ||= request.headers[access_token_name] || params[access_token_name]
    @client_id ||= request.headers[client_name] || params[client_name]

    # client_id isn't required, set to 'default' if absent
    @client_id ||= 'default'
    # check for an existing user, authenticated via warden/devise, if enabled
    if DeviseTokenAuth.enable_standard_devise_support
      binding.pry
      devise_warden_user = warden.user(rc.to_s.underscore.to_sym)
      if devise_warden_user && devise_warden_user.tokens[@client_id].nil?
        @used_auth_by_token = false
        @resource = devise_warden_user
        # REVIEW: The following line _should_ be safe to remove;
        #  the generated token does not get used anywhere.
        # @resource.create_new_auth_token
      end
    end

    # user has already been found and authenticated
    return @resource if @resource && @resource.is_a?(rc)

    # ensure we clear the client_id
    if !@token
      @client_id = nil
      return
    end

    return false unless @token

    # mitigate timing attacks by finding by uid instead of auth token
    user = uid && rc.find_by(uid: uid)

    if user && user.valid_token?(@token, @client_id)
      # sign_in with bypass: true will be deprecated in the next version of Devise
      if self.respond_to?(:bypass_sign_in) && DeviseTokenAuth.bypass_sign_in
        bypass_sign_in(user, scope: :user)
      else
        sign_in(:user, user, store: false, event: :fetch, bypass: DeviseTokenAuth.bypass_sign_in)
      end
      return @resource = user
    else
      # zero all values previously set values
      @client_id = nil
      return @resource = nil
    end
    end

здесь, в самом конце, он попадает в else и возвращает ресурс как ноль, так как другие условия не были выполнены.

Любая помощь будет принята с благодарностью, я уверен, что проблема именно в этом, потому что я отлаживал ее в течение нескольких дней, и вот куда она меня привела.

1 ответ

Решение

Если вы здесь, потому что у вас была та же проблема, я надеюсь, я смогу помочь! после нескольких часов изнурительной отладки и тестирования, которые я преодолел, это может быть обходной или дурацкий способ сделать это, но он работает, все еще используя метод devise.

в вашем passwords_controller.rb должно быть "before_action:set_user_by_token, only: => [:update]"

замените ":set_user_by_token" на то, что вы хотите назвать новым методом, который мы собираемся сделать, затем скопируйте и вставьте метод в исходное сообщение и внесите некоторые небольшие изменения.

изменить эти строки:

    uid          = request.headers[uid_name] || params[uid_name]
    @token     ||= request.headers[access_token_name] || params[access_token_name]
    @client_id ||= request.headers[client_name] || params[client_name]

в

uid          = params[uid_name]
@token     ||= params[access_token_name]
@client_id ||= params[client_name]

и сделано. Теперь вам не нужно связываться с инициализаторами или концепциями!

надеюсь, я помог кому-то!

Другие вопросы по тегам