devise_token_auth всегда возвращает 401 Unauthorized

Я работаю над приложением Angular с API Rails. Я использую Devise Token Auth и 6.x ветвь angular-token. Я без проблем могу CRUD-пользователей и могу войти в систему, но когда я пытаюсь получить доступ к ресурсу с ограниченным доступом (ограниченному с помощью помощника before_action :authenticate_user!), я получаю сообщение об ошибке независимо от того, вошел я в систему или нет.

Соответствующий контроллер:

class QuestionsController < ApplicationController
    before_action :authenticate_user!

    # GET /questions.json
    def index
      @questions = Question.all

      # This code is never reached due to the :authenticate_user! helper, 
      # but when I comment it out, I get the following:
      puts user_signed_in?  # => false
      puts current_user     # => nil

      render json: @questions
    end

Несколько вещей:

  • Я определенно вошел в систему в соответствии с angular-token -- TokenService.UserSignedIn() возвращает true во время 401 Unauthorized response.
  • Я включил CORS.
  • Я выставил следующие заголовки в конфиге Rack-Cors: ['access-token', 'expiry', 'token-type', 'uid', 'client'].

Любая помощь будет принята с благодарностью.

Пример ответа при входе:

{
    "data": {
        "id": 1,
        "email": "[email protected]",
        "provider": "email",
        "uid": "[email protected]",
        "allow_password_change": false,
        "name": null,
        "nickname": null,
        "image": null
    }
}

Код Angular:

this.authService.loginUser({
  login: '',
  password: ''
})
.subscribe(resp => {
    if (resp.status === 200) {
      this.router.navigate(['/']);
    }
  },
  err => {
    // cut for brevity
});

Изменить:

Я понял, что проблема в том, что angular-token не устанавливает заголовки аутентификации из-за того, что я считаю ошибкой в ​​​​следующем коде:

// Add the headers if the request is going to the configured server
if (this.tokenService.currentAuthData && req.url.match(this.tokenService.apiPath)) {
  (<any>Object).assign(baseHeaders, {
    'access-token': this.tokenService.currentAuthData.accessToken,
    'client':       this.tokenService.currentAuthData.client,
    'expiry':       this.tokenService.currentAuthData.expiry,
    'token-type':   this.tokenService.currentAuthData.tokenType,
    'uid':          this.tokenService.currentAuthData.uid
  });
}

Поскольку я не определил apiPath, req.url.match(this.tokenService.apiPath)) оценивается как false и, таким образом, заголовки никогда не добавляются.


person Niek    schedule 02.07.2018    source источник
comment
Можете ли вы показать нам пример использования почтальона? пример входа, чтобы увидеть, что вернет сервер rails. И ваш угловой код, когда вы вызываете свой API.   -  person El Fadel Anas    schedule 02.07.2018
comment
Я добавил примеры. Обратите внимание, что сам по себе вход работает нормально, проблема именно в запросах к ресурсам.   -  person Niek    schedule 02.07.2018
comment
мне нужно увидеть заголовок вашего ответа. Заголовок вашего ответа должен содержать следующие параметры: токен доступа — uid — клиент — срок действия. Эти параметры должны быть сохранены и после этого добавлены в каждый сделанный вами HTTP-запрос. ты это уже сделал?   -  person El Fadel Anas    schedule 02.07.2018
comment
Да, заголовки ответа включают все эти заголовки. Хранение токена — это то, для чего предназначен angular-token.   -  person Niek    schedule 02.07.2018
comment
Нет, даже с угловым токеном вам нужно установить заголовок вашего запроса, если вы его не установили, я думаю, что это ошибка.   -  person El Fadel Anas    schedule 02.07.2018


Ответы (1)


Я не знаю об angular-token, но у меня была такая же проблема с моим приложением на основе React/Redux - оказывается, это действительно была просто проблема с отсутствием или неправильной установкой заголовков.

По какой-то причине кажется, что контроллеры на основе DeviseTokenAuth:: могут работать только при установке client и access-token, но для всех других ресурсов, защищенных DeviseTokenAuth::Concerns::SetUserByToken, вы должны установить заголовки all точно так, как ожидалось и задокументировано devise_token_auth.

  • Проверьте значения и форматы заголовков.
  • Убедитесь, что заголовки точно совпадают с заголовком, возвращенным последним запросом (запросом аутентификации в вашем случае).
  • Кроме того, проверьте свое сопоставление

In config/initializers/devise_token_auth.rb :

config.headers_names = {:'access-token' => 'access-token',
                     :'client' => 'client',
                     :'expiry' => 'expiry',
                     :'uid' => 'id',
                     :'token-type' => 'token-type' }

(он определяет имя ожидаемых заголовков http (а не атрибуты models/activerecords)).

person nakwa    schedule 26.07.2018