devise_token_auth с devise для маршрутов без devise

Я пытаюсь заставить devise + devise_token_auth работать вместе, используя «enable_standard_devise_support = true» и без необходимости дублировать каждый контроллер, один для Интернета, а другой для API.

Я включаю стандартную поддержку разработки в инициализаторе

        : config.enable_standard_devise_support = true

И настроить мои маршруты как вложенные

        :   namespace :api, defaults: {format: 'json'} do # namespace devise token routes to stop duplication
        :     namespace :v1 do
        :       mount_devise_token_auth_for 'User', at: 'auth'
        :     end
        :   end

Домашний маршрут по-прежнему находится за пределами API

        : resources :home, only: [:index]
        : root to: "home#index"

У меня есть API application_controller.rb с;

        : module Api
        :   module V1
        :     class ApplicationController < ActionController::API
        :       include DeviseTokenAuth::Concerns::SetUserByToken
        :       before_action :authenticate_user!
        :       before_action :configure_permitted_parameters, if: :devise_controller?
        :       
        :       protected
        : 
        :       def configure_permitted_parameters
        :         devise_parameter_sanitizer.permit(:sign_in, keys: [:email, :password])
        :       end
        :     end
        :   end
        : end

и application_controller.rb с;

        : class ApplicationController < ActionController::Base
        :   protect_from_forgery unless: -> { request.format.json? }
        : end

Почему другие мои маршруты, такие как home#index, не работают?

Ошибка, которую я получаю от доступа devise_token_auth к области /home.json

        : Successfully synced application org.nativescript.NativeScriptTemplate2 on device emulator-5586.
        : JS: Angular is running in the development mode. Call enableProdMode() to enable the production mode.
        : JS: Login called
        : JS: Logged in: 06rD-pZ-kstw_YZO7cWTCQ
        : JS: ERROR {
        : JS:   "headers": {
        : JS:     "normalizedNames": {},
        : JS:     "lazyUpdate": null
        : JS:   },
        : JS:   "status": 401,
        : JS:   "statusText": "Unauthorized",
        : JS:   "url": "http://192.168.200.4:3000/[email protected]&client=vRardfTGtk10YTXwz8cSRg&access-token=06rD-pZ-kstw_YZO7cWTCQ",
        : JS:   "ok": false,
        : JS:   "name": "HttpErrorResponse",
        : JS:   "message": "Http failure response for http://192.168.200.4:3000/[email protected]&client=vRardfTGtk10YTXwz8cSRg&access-token=06rD-pZ-kstw_YZO7cWTCQ: 401 Unauthorized",
        : JS:   "error": {
        : JS:     "error": "You need to sign in or sign up before continuing."
        : JS:   }
        : JS: }

Вот домашний контроллер

class HomeController < ApplicationController
  before_action :authenticate_user!

  respond_to :html, :json

  def index
    respond_to do |format|
      format.html
      format.json { render json: {message: "Welcome to the Ruby on Rails backend"} }
    end
  end
end

Обновление: тестирование с помощью curl

Вот код моего шаблона: https://github.com/map7/backend_rails6_template

Если я протестирую API с помощью команд curl, я смогу воспроизвести проблему;

При фиксации «102bb24» API не работает для домашнего маршрута, но веб-представления работают.

Авторизоваться

curl -i -X POST http://localhost:3000/api/v1/auth/sign_in.json -F [email protected] -F password=password

Получите следующую страницу с учетными данными (обратите внимание, что вам нужно будет вставить клиент и токен доступа, который вы получите из заголовков входа)

curl -i -X GET http://localhost:3000/home.json\?uid\[email protected]\&client\=UQPxKFYEQ1GcaA_PpIjx2Q\&access-token\=PTR-jCn8xgg6GfZ2Fu5QeA

Ошибка, которую я получаю

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Cache-Control: no-cache
X-Request-Id: a746a91c-bffa-405a-8b17-a5dd0ce37df1
X-Runtime: 0.012248
Vary: Origin
Transfer-Encoding: chunked

{"error":"You need to sign in or sign up before continuing."}% 

ПРИМЕЧАНИЕ. Чтобы увидеть рабочий пример, сначала попробуйте зафиксировать «e475478». Эта фиксация работает для API, но не для веб-представлений.


person map7    schedule 17.06.2020    source источник


Ответы (2)


Попробуйте создать App::BaseController

И поместите метод аутентификации здесь:

class App::BaseController < ApplicationController
  before_action :authenticate_user!
end

Теперь наследуйте App::BaseController для всех контроллеров, которые вы хотите авторизовать.

person prabessh    schedule 17.06.2020

Мне пришлось создать отдельный контроллер для API и поместить этот отдельный контроллер в маршруты, чтобы он работал.

Домашний контроллер API

          : module Api
          :   module V1
          :     class HomeController < ApplicationController
          :       before_action :authenticate_user!
          :       
          :       def index
          :         render json: {message: "Welcome to the Ruby on Rails backend"}
          :       end
          :     end
          :   end
          : end

Домашний HTML-контроллер

          : class HomeController < ApplicationController
          :   before_action :authenticate_user!
          : end

Маршруты

          : Rails.application.routes.draw do
          :   devise_for :users             # Standard devise routes must come first!
          :   resources :home, only: [:index]
          :   root to: "home#index"
          : 
          :   namespace :api, defaults: {format: 'json'} do
          :     namespace :v1 do
          :       mount_devise_token_auth_for 'User', at: 'auth'
          :       resources :home, only: [:index]
          :     end
          :   end
          :   
          : end
person map7    schedule 22.04.2021