Rails не может получить токен-носитель из поля авторизации при запросе http-заголовка.Я думаю, что проблема с отложенным обновлением - PullRequest
0 голосов
/ 08 мая 2019

Я создаю приложение RoR, которое включает API REST для связи с мобильным приложением. У меня есть маршрут аутентификации, который генерирует маркер аутентификации, который может получить мобильный пользователь, и он должен отправить его по дальнейшим запросам.

Я делал эту функцию несколько раз в прошлом, и она отлично работала. Сегодня, когда я попытался реализовать его в своем новом проекте, в части кода, в которой сервер rails получает поле аутентификации из запроса заголовков HTTP, я сам удивился, когда получил сообщение об ошибке, сообщающее, что запрашиваемое поле было ноль, хотя я использовал мой прежний старомодный код, чтобы сделать запрос.

Мое первое предположение состояло в том, что мой код на мобильной стороне был неправильным, но после некоторой сессии отладки я обнаружил, что запрос был в порядке, но это был сервер, который не смог получить поле Авторизация. Изучив журнал сервера, я обнаружил, что параметры, которые я получал, действительно имеют токен авторизации И это правильное значение. Вот вам пример сообщения:

Started POST "/api/user_this_week.json" for 192.168.0.14 at 2019-05-07 20:00:30 -0400
Cannot render console from 192.168.0.14! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by Api::UsersController#this_week as JSON
Parameters: {"headers"=>{"normalizedNames"=>{}, "lazyUpdate"=>[{"name"=>"Authorization", "value"=>"eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE1NTczNTYyNzd9.QcYnXDWWdZh5PlkiYrt-vuofwy9wo3N-zH5w2iSvz9s", "op"=>"s"}], "headers"=>{}, "lazyInit"=>{"normalizedNames"=>{}, "lazyUpdate"=>nil, "headers"=>{}}}, "user"=>{}}
Filter chain halted as :authenticate_request rendered or redirected
Completed 401 Unauthorized in 1ms (Views: 0.1ms | ActiveRecord: 0.0ms)

Я сравнил этот запрос, запустив свое старое приложение и отправив запросы с другим моим мобильным приложением, и разница в том, что на рабочем сервере у меня нет такого странного поля, которое говорит что-то вроде "lazyUpdate" или "lazyInit" .

Я использую gem simple_command , чтобы создать класс для декодирования заголовка и дать мне поле user_id, и я создаю экземпляр объекта в моем ApplicationController всякий раз, когда я получаю запрос soe к моему API, используя фильтр before_action для эти api контроллер.

приложение / контроллеры / application_controller.rb

    def authenticate_request
      @current_user_movil = AuthorizeApiRequest.call(request.headers).result
      render json: { error: 'Not Authorized' }, status: 401 unless @current_user_movil
    end

приложение / команды / authorize_api_request.rb

class AuthorizeApiRequest
  prepend SimpleCommand

  def initialize(headers = {})
    @headers = headers
  end

  def call
    user
  end

  private

    attr_reader :headers

    def user
      @user ||= User.find(decoded_auth_token[:user_id]) if decoded_auth_token
      @user || errors.add(:token, 'Invalid token') && nil
    end

    def decoded_auth_token
      @decoded_auth_token ||= JsonWebToken.decode(http_auth_header)
    end

    def http_auth_header
      if headers['Authorization'].present?
        return headers['Authorization'].split(' ').last
      else
        errors.add(:token, 'Missing token')
      end
      nil
    end
end

Строка, которая возвращает nil, относится к закрытому методу http_auth_header: return headers ['Authorization']. Split ('') .last

Я считаю, что какой-то драгоценный камень, который я использую, был обновлен, и в этом обновлении изменилось поведение по умолчанию, и теперь переменные запроса и заголовка могут обновляться лениво, поэтому всякий раз, когда я пытаюсь получить их, используя заголовки [' Authorizarion '], значение еще не обновлено, и мне не хватает чего-то, чтобы сообщить rails, что оно мне нужно для оценки выражения.

Или, может быть, я должен переместить код в другое место? Может быть, за простое обновление отвечает гем simple_command? Но я использую rails 5.2.3 в двух моих приложениях, а гем simple_command находится в версии 0.0.9 для обоих приложений. Может быть, это опечатка, которую я делаю? Это как тупик.

Любые отзывы будут очень приветствоваться. Если вам нужна дополнительная информация, я буду рад ее предоставить.

Заранее спасибо.

...