JWT「続行する前にサインインまたはサインアップする必要があります」を工夫する
概要
あなたは私の最後のチャンスです Device_token_auth から Device-jwt に移行しようとします ユーザーにサインインしようとすると、「続行する前にサインインまたはサインアップする必要があります。」と応答するよう工夫してください。 構成:
私のコードがあります:
module Api
module V2
module Devise
class SessionsController < ::Devise::SessionsController
skip_before_action :verify_authenticity_token
include ::Api::V2::Concerns::Response
respond_to :json
private
def respond_with(resource, _opts = {})
render_json ::V2::UserSerializer.new(resource)
end
def respond_to_on_destroy
head :ok
end
end
end
end
end
Routes.rb の一部:
Rails.application.routes.draw do
scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/, defaults: { format: 'json' } do
namespace :api do
namespace :v2 do
devise_for :users, path: 'auth',
skip: %i[passwords], controllers: {
registrations: 'api/v2/devise/registrations',
sessions: 'api/v2/devise/sessions'
}
resources :destinations, only: :index
resources :photos, only: :index
scope :user do
resources :client_contracts, only: :index, module: :user
resources :contracts_houses, only: :index, module: :user
resource :owner_certificate, only: :show, module: :user
end
end
end
end
end
(私はadmin_users(jwtではなく)でも動作するように工夫しており、api_v1_userのdevice_token_authのルートを無効にしました:)
mount_devise_token_auth_for 'User', at: 'auth',
skip: %i[confirmations passwords registrations sessions
token_validations]
イニシャライザを工夫してください:
config.skip_session_storage = %i[http_auth]
config.navigational_formats = ['*/*', :html, :pdf]
config.jwt do |jwt|
jwt.secret = ENV['DEVISE_JWT_SECRET_KEY']
jwt.expiration_time = 1.day.to_i
end
ユーザーモデル:
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable,
:jwt_authenticatable, jwt_revocation_strategy: JWTDenylist
self.skip_session_storage = %i[http_auth params_auth]
新しいユーザーを登録しようとしましたが、機能しますが、ヘッダーにJWTではなくCookie(デバイスリターンCookie)が使用されています…
conf を工夫してください:
> Devise::JWT.config
=> #<Dry::Configurable::Config values={:secret=>"secret", :expiration_time=>86400, :dispatch_requests=>[["POST", /^\/(:locale)\/api\/v2\/auth\/sign_in$/], ["POST", /^\/(\/:locale)\/api\/v1\/auth\/sign_in$/], ["POST", /^\/(\/:locale)\/api\/v1\/auth$/], ["POST", /^\/(\/:locale)\/api\/v2\/auth\/sign_in$/], ["POST", /^\/(\/:locale)\/api\/v2\/auth$/]], :revocation_requests=>[], :aud_header=>"JWT_AUD", :request_formats=>{}}>
> Warden::JWTAuth.config
=> #<Dry::Configurable::Config values={:secret=>"secret", :algorithm=>"HS256", :expiration_time=>86400, :aud_header=>"JWT_AUD", :mappings=>{:api_v1_user=>User (call 'User.connection' to establish a connection), :api_v2_user=>User (call 'User.connection' to establish a connection)}, :dispatch_requests=>[["POST", /^\/(:locale)\/api\/v2\/auth\/sign_in$/], ["POST", /^\/(\/:locale)\/api\/v1\/auth\/sign_in$/], ["POST", /^\/(\/:locale)\/api\/v1\/auth$/], ["POST", /^\/(\/:locale)\/api\/v2\/auth\/sign_in$/], ["POST", /^\/(\/:locale)\/api\/v2\/auth$/]], :revocation_requests=>[["DELETE", /^\/(\/:locale)\/api\/v1\/auth\/sign_out$/], ["DELETE", /^\/(\/:locale)\/api\/v2\/auth\/sign_out$/]], :revocation_strategies=>{:api_v1_user=>JWTDenylist (call 'JWTDenylist.connection' to establish a connection), :api_v2_user=>JWTDenylist (call 'JWTDenylist.connection' to establish a connection)}}>
> Devise.mappings
=> {:admin_admin_user=>#<Devise::Mapping:0x0000555fd7602188 @scoped_path="admin/admin_users", @singular=:admin_admin_user, @class_name="AdminUser", @klass=#<Devise::Getter:0x0000555fd7601ad0 @name="AdminUser">, @path="admin_users", @path_prefix="(/:locale)/admin", @sign_out_via=:delete, @format=nil, @router_name=nil, @failure_app=Devise::FailureApp, @controllers={:registrations=>"admin/devise/registrations", :sessions=>"admin/devise/sessions", :passwords=>"admin/devise/passwords"}, @path_names={:registration=>"", :new=>"new", :edit=>"edit", :sign_in=>"sign_in", :sign_out=>"sign_out", :password=>"password"}, @modules=[:database_authenticatable, :recoverable], @routes=[:session, :password], @used_routes=[:session, :password], @used_helpers=[:session, :password]>, :api_v1_user=>#<Devise::Mapping:0x0000555fd6e718d8 @scoped_path="api_v1/users", @singular=:api_v1_user, @class_name="User", @klass=#<Devise::Getter:0x0000555fd6e71720 @name="User">, @path="auth", @path_prefix="(/:locale)/api/v1", @sign_out_via=:delete, @format=nil, @router_name=nil, @failure_app=Devise::FailureApp, @controllers={:unlocks=>"devise_token_auth/unlocks"}, @path_names={:registration=>"", :new=>"new", :edit=>"edit"}, @modules=[:database_authenticatable, :rememberable, :recoverable, :registerable, :validatable, :jwt_authenticatable], @routes=[:session, :password, :registration], @used_routes=[], @used_helpers=[:session, :password, :registration]>, :api_v2_user=>#<Devise::Mapping:0x0000555fd60297f8 @scoped_path="api_v2/users", @singular=:api_v2_user, @class_name="User", @klass=#<Devise::Getter:0x0000555fd60292d0 @name="User">, @path="auth", @path_prefix="(/:locale)/api/v2", @sign_out_via=:delete, @format=nil, @router_name=nil, @failure_app=Devise::FailureApp, @controllers={:registrations=>"api/v2/devise/registrations", :sessions=>"api/v2/devise/sessions"}, @path_names={:registration=>"", :new=>"new", :edit=>"edit", :sign_in=>"sign_in", :sign_out=>"sign_out", :sign_up=>"sign_up", :cancel=>"cancel"}, @modules=[:database_authenticatable, :rememberable, :recoverable, :registerable, :validatable, :jwt_authenticatable], @routes=[:session, :password, :registration], @used_routes=[:session, :registration], @used_helpers=[:session, :password, :registration]>}
解決策
私も同じ問題を抱えていましたが、名前空間内でdevice_forを実行すると、Deviseコントローラーがresource_nameをapi/v1/user(またはそのようなもの)に割り当てることに気付きました。
Devices_for をすべての名前空間ブロックの外に移動して、そのパスをパス「api/v2/auth」に変更してみてはいかがでしょうか。
これは役立つはずだと思います!そうなったことを教えてください、お願いします