Giter Site home page Giter Site logo

nejdetkadir / devise-api Goto Github PK

View Code? Open in Web Editor NEW
134.0 3.0 22.0 95 KB

The devise-api gem is a convenient way to add authentication to your Ruby on Rails application using the devise gem. It provides support for access tokens and refresh tokens, which allow you to authenticate API requests and keep the user's session active for a longer period of time on the client side

License: MIT License

Ruby 89.67% Shell 0.09% HTML 9.73% JavaScript 0.04% CSS 0.48%
devise devise-gem-extension devise-jwt devise-token-auth rails rails-api rails-api-backend rails-gem devise-api devise-api-authenticatable

devise-api's Introduction

devise-api's People

Contributors

codescaptain avatar derekcrosson avatar k-p-jones avatar nejdetkadir avatar plus17 avatar theovrr avatar wuletawwonte avatar xkraty avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

devise-api's Issues

Allow configuring additional fields for API registration

The devise-api gem currently only allows for email and password fields during user registration through the API. It would be useful to have the ability to specify additional fields that are required or accepted during registration, such as name or address. This would provide more flexibility in terms of user registration through the API. It would be great if this feature could be added to the gem.

No cookies created on sign up/sign in/refresh token

I don't seem to get a cookie.
I receive a token and a refresh token response, but no cookies are returned.
My model user is rememberable

#models/user.rb
class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :api
  validates :name, presence: true, length: { minimum: 1 }
  has_many :battle_decks, dependent: :destroy

  end
#config/initializers/devise.rb
Devise.setup do |config|

  config.api.configure do |api|
    # Access Token
    api.access_token.expires_in = 1.hour
    api.access_token.expires_in_infinite = ->(_resource_owner) { false }
    api.access_token.generator = ->(_resource_owner) { Devise.friendly_token(60) }


    # Refresh Token
    api.refresh_token.enabled = true
    api.refresh_token.expires_in = 1.week
    api.refresh_token.generator = ->(_resource_owner) { Devise.friendly_token(60) }
    api.refresh_token.expires_in_infinite = ->(_resource_owner) { false }


    # Authorization
    api.authorization.key = 'Authorization'
    api.authorization.scheme = 'Bearer'
    api.authorization.location = :both # :header or :params or :both
    api.authorization.params_key = 'access_token'


    # Base classes
    api.base_token_model = 'Devise::Api::Token'
    api.base_controller = '::DeviseController'


    # After successful callbacks
    api.after_successful_sign_in = ->(_resource_owner, _token, _request) { }
    api.after_successful_sign_up = ->(_resource_owner, _token, _request) { }
    api.after_successful_refresh = ->(_resource_owner, _token, _request) { }
    api.after_successful_revoke = ->(_resource_owner, _token, _request) { }


    # Before callbacks
    api.before_sign_in = ->(_params, _request, _resource_class) { }
    api.before_sign_up = ->(_params, _request, _resource_class) { }
    api.before_refresh = ->(_params, _request) { }
    api.before_revoke = ->(_params, _request) { }
  end
  config.mailer_sender = '[email protected]'
  require 'devise/orm/active_record'
  config.case_insensitive_keys = [:email]
  config.strip_whitespace_keys = [:email]
  config.skip_session_storage = [:http_auth]
  config.stretches = Rails.env.test? ? 1 : 12
  config.reconfirmable = true
  config.expire_all_remember_me_on_sign_out = true
  config.extend_remember_period = true
  config.rememberable_options = { secure: false }
  config.password_length = 6..128
  config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
  config.reset_password_within = 6.hours
  config.sign_out_via = :delete
  config.responder.error_status = :unprocessable_entity
  config.responder.redirect_status = :see_other
end
#api/v1/users/token_controller.rb
# frozen_string_literal: true

class Api::V1::Users::TokensController < Devise::Api::TokensController
  def sign_in
    Devise.api.config.before_sign_in.call(sign_in_params, request, resource_class)
    service = Devise::Api::ResourceOwnerService::SignIn.new(params: sign_in_params,
                                                            resource_class: resource_class).call
    if service.success?
      token = service.success
      call_devise_trackable!(token.resource_owner)
      token_response = Devise::Api::Responses::TokenResponse.new(request, token: service.success,
                                                                 action: __method__)
      Devise.api.config.after_successful_sign_in.call(token.resource_owner, token, request)
      return render json: token_response.body, status: token_response.status
    end
    error_response = Devise::Api::Responses::ErrorResponse.new(request,
                                                               resource_class: resource_class,
                                                               **service.failure)
    render json: error_response.body, status: error_response.status
  end
 
  private
    def sign_up_params
      params.permit(:name, *resource_class.authentication_keys,
                    *::Devise::ParameterSanitizer::DEFAULT_PERMITTED_ATTRIBUTES[:sign_up]).to_h
    end
end

image

ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "resource_owner_id"

Hi,

i've tried to do what you suggest in #11 . I've created a new migration :

class ChangeUuidColumnType < ActiveRecord::Migration[7.0] def change change_column :devise_api_tokens, :resource_owner_id, :primary_key end end

and I get this error :

== 20230529143952 ChangeUuidColumnType: migrating =============================
-- change_column(:devise_api_tokens, :resource_owner_id, :primary_key)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

PG::SyntaxError: ERROR: syntax error at or near "primary"
LINE 1: ..." ALTER COLUMN "resource_owner_id" TYPE bigserial primary ke...

Did I miss something ?

Unable to set extra parameters during sign_in

My apologies if I've missed something obvious here, as I'm new to devise-api.

I'm attempting to use a User model that has extra required fields. I updated my application_controller to permit name, but it seems to not be passing through.

Any advice on what I can do to debug and resolve this? Should I keep all non-user related stuff out of the user table instead?

Thanks much!

** Versions **
Ruby: 3.2.2
Rails: 7.0.8
Devise: 4.9
Devise-api: 0.1.3

*** app/controllers/application_controller: ***

class ApplicationController < ActionController::API
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    puts "Made it into configure_permitted_parameters"
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
    puts "Leaving configure_permitted_parameters"

  end
end

*** My user schema ***

...
  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "username"
    t.string "name", null: false
    t.string "image"
    t.date "birthday"
    t.string "uuid"
    t.integer "family_id"
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["family_id"], name: "index_users_on_family_id"
    t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
    t.index ["username"], name: "index_users_on_username", unique: true
  end
...
    add_foreign_key "users", "families"
...
add_foreign_key "users", "families"
...

*** Rails during run ***

~/code/billmebabe-api$ rails s
=> Booting Puma
=> Rails 7.0.8 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 5.6.7 (ruby 3.2.2-p53) ("Birdie's Version")
*  Min threads: 5
*  Max threads: 5
*  Environment: development
*          PID: 57192
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
Started POST "/users/tokens/[email protected]&password=[FILTERED]&name=John%20Doe" for 127.0.0.1 at 2023-10-06 06:38:55 +0700
  ActiveRecord::SchemaMigration Pluck (0.1ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
Processing by Devise::Api::TokensController#sign_up as */*
  Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]", "name"=>"John Doe"}
Made it into configure_permitted_parameters
Leaving configure_permitted_parameters
Unpermitted parameter: :name. Context: { controller: Devise::Api::TokensController, action: sign_up, request: #<ActionDispatch::Request:0x0000000114910c98>, params: {"email"=>"[email protected]", "password"=>"[FILTERED]", "name"=>"John Doe", "controller"=>"devise/api/tokens", "action"=>"sign_up"} }
Unpermitted parameter: :name. Context: { controller: Devise::Api::TokensController, action: sign_up, request: #<ActionDispatch::Request:0x0000000114910c98>, params: {"email"=>"[email protected]", "password"=>"[FILTERED]", "name"=>"John Doe", "controller"=>"devise/api/tokens", "action"=>"sign_up"} }
  TRANSACTION (0.0ms)  begin transaction
  User Exists? (0.2ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = ? LIMIT ?  [["email", "[email protected]"], ["LIMIT", 1]]
  User Create (0.3ms)  INSERT INTO "users" ("email", "encrypted_password", "reset_password_token", "reset_password_sent_at", "remember_created_at", "created_at", "updated_at", "username", "name", "image", "birthday", "uuid", "family_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["email", "[email protected]"], ["encrypted_password", "$2a$12$ocbHzTLGJiibSsYAFX43cuS1cJy7eQXouEJkZ/MqFdBY1xa8hms8u"], ["reset_password_token", nil], ["reset_password_sent_at", nil], ["remember_created_at", nil], ["created_at", "2023-10-05 23:38:55.655499"], ["updated_at", "2023-10-05 23:38:55.655499"], ["username", nil], ["name", nil], ["image", nil], ["birthday", nil], ["uuid", nil], ["family_id", nil]]
  TRANSACTION (0.0ms)  rollback transaction
Completed 500 Internal Server Error in 272ms (ActiveRecord: 1.0ms | Allocations: 47337)

Add example API requests to README

The devise-api gem provides a convenient way to add authentication to Ruby on Rails applications, but the README currently lacks examples of how to use the gem to make API requests. It would be helpful for users to see examples of how to authenticate with access tokens and refresh tokens

Unpermitted parameter: :token

When issuing the example curl call:
curl --location --request POST 'http://127.0.0.1:3000/users/tokens/sign_up' --header 'Content-Type: application/json' --data-raw '{ "email": "[email protected]", "password": "123456" }' I do get a response of: {"token":"xmRbTRpBxbCkyN9Rgzs6_usJTb_wFnB7qL36fioh5bTLa8XAQTwca-12vz3P","refresh_token":"eigFtc3nPqTR41KJh7ktRiCtVqsM6n4izBx6yzNzqKjURyZ9vqz7McRbunSf","expires_in":3600,"token_type":"Bearer","resource_owner":{"id":2,"email":"[email protected]","created_at":"2023-02-24T22:12:38.043Z","updated_at":"2023-02-24T22:12:38.043Z"}}

But, the rails logs contain:
Processing by Devise::Api::TokensController#sign_up as */* Parameters: {"email"=>"[email protected]", "password"=>"[FILTERED]", "token"=>{}} Unpermitted parameter: :token. Context: { controller: Devise::Api::TokensController, action: sign_up, request: #<ActionDispatch::Request:0x000000010ed12950>, params: {"email"=>"[email protected]", "password"=>"[FILTERED]", "controller"=>"devise/api/tokens", "action"=>"sign_up", "token"=>{}} } Unpermitted parameter: :token. Context: { controller: Devise::Api::TokensController, action: sign_up, request: #<ActionDispatch::Request:0x000000010ed12950>, params: {"email"=>"[email protected]", "password"=>"[FILTERED]", "controller"=>"devise/api/tokens", "action"=>"sign_up", "token"=>{}} }

Any ideas?

undefined local variable or method `resource_class'

Hello, thanks for your work!

I'm trying to figure out if I'm missing something or if it is a bug.
I'm doing some tests with a clean install and default configuration and yet in case of an invalid or empty token I get undefined local variable or method 'resource_class', I found a workaround by defining a resource_class method in my Api::ApplicationController which doesn't seems to affect the correct behavior.

Thanks for your support!
xKraty

# frozen_string_literal: true

module Api
  class ApplicationController < ActionController::Base
    skip_before_action :verify_authenticity_token, raise: false
    before_action :authenticate_devise_api_token!

    # Workaround to return errors in case of an invalid token
    def resource_class
      User
    end
  end
end
# frozen_string_literal: true

module Api
  class HealthController < ::Api::ApplicationController
    def index
      render json: { message: 'Ready to roll! '}
    end
  end
end
curl --location 'http://localhost:3000/api/health.json' \
--header 'Authorization: Bearer an-invalid-token' \
NameError (undefined local variable or method `resource_class' for #<Api::HealthController:0x00000000024e78>):

devise-api (0.1.2) lib/devise/api/controllers/helpers.rb:14:in `authenticate_devise_api_token!'
activesupport (7.0.5) lib/active_support/callbacks.rb:400:in `block in make_lambda'
activesupport (7.0.5) lib/active_support/callbacks.rb:199:in `block (2 levels) in halting'
actionpack (7.0.5) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
activesupport (7.0.5) lib/active_support/callbacks.rb:200:in `block in halting'
activesupport (7.0.5) lib/active_support/callbacks.rb:595:in `block in invoke_before'
activesupport (7.0.5) lib/active_support/callbacks.rb:595:in `each'
activesupport (7.0.5) lib/active_support/callbacks.rb:595:in `invoke_before'
activesupport (7.0.5) lib/active_support/callbacks.rb:116:in `block in run_callbacks'
actiontext (7.0.5) lib/action_text/rendering.rb:20:in `with_renderer'
actiontext (7.0.5) lib/action_text/engine.rb:69:in `block (4 levels) in <class:Engine>'
activesupport (7.0.5) lib/active_support/callbacks.rb:127:in `instance_exec'
activesupport (7.0.5) lib/active_support/callbacks.rb:127:in `block in run_callbacks'
activesupport (7.0.5) lib/active_support/callbacks.rb:138:in `run_callbacks'
actionpack (7.0.5) lib/abstract_controller/callbacks.rb:233:in `process_action'
actionpack (7.0.5) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (7.0.5) lib/action_controller/metal/instrumentation.rb:67:in `block in process_action'
activesupport (7.0.5) lib/active_support/notifications.rb:206:in `block in instrument'
activesupport (7.0.5) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (7.0.5) lib/active_support/notifications.rb:206:in `instrument'
actionpack (7.0.5) lib/action_controller/metal/instrumentation.rb:66:in `process_action'
actionpack (7.0.5) lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord (7.0.5) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (7.0.5) lib/abstract_controller/base.rb:151:in `process'
actionview (7.0.5) lib/action_view/rendering.rb:39:in `process'
actionpack (7.0.5) lib/action_controller/metal.rb:188:in `dispatch'
actionpack (7.0.5) lib/action_controller/metal.rb:251:in `dispatch'
actionpack (7.0.5) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (7.0.5) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (7.0.5) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.5) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.5) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.5) lib/action_dispatch/routing/route_set.rb:852:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.7) lib/rack/static.rb:161:in `call'
warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
warden (1.2.9) lib/warden/manager.rb:34:in `catch'
warden (1.2.9) lib/warden/manager.rb:34:in `call'
rack (2.2.7) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.7) lib/rack/etag.rb:27:in `call'
rack (2.2.7) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.7) lib/rack/head.rb:12:in `call'
actionpack (7.0.5) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
actionpack (7.0.5) lib/action_dispatch/http/content_security_policy.rb:36:in `call'
rack (2.2.7) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.7) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/cookies.rb:704:in `call'
activerecord (7.0.5) lib/active_record/migration.rb:603:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.5) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.5) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
web-console (4.2.0) lib/web_console/middleware.rb:132:in `call_app'
web-console (4.2.0) lib/web_console/middleware.rb:28:in `block in call'
web-console (4.2.0) lib/web_console/middleware.rb:17:in `catch'
web-console (4.2.0) lib/web_console/middleware.rb:17:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/show_exceptions.rb:26:in `call'
railties (7.0.5) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.5) lib/rails/rack/logger.rb:25:in `block in call'
activesupport (7.0.5) lib/active_support/tagged_logging.rb:99:in `block in tagged'
activesupport (7.0.5) lib/active_support/tagged_logging.rb:37:in `tagged'
activesupport (7.0.5) lib/active_support/tagged_logging.rb:99:in `tagged'
railties (7.0.5) lib/rails/rack/logger.rb:25:in `call'
sprockets-rails (3.4.2) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.7) lib/rack/method_override.rb:24:in `call'
rack (2.2.7) lib/rack/runtime.rb:22:in `call'
activesupport (7.0.5) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/server_timing.rb:61:in `block in call'
actionpack (7.0.5) lib/action_dispatch/middleware/server_timing.rb:26:in `collect_events'
actionpack (7.0.5) lib/action_dispatch/middleware/server_timing.rb:60:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.7) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.5) lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
rack-mini-profiler (3.1.0) lib/mini_profiler.rb:413:in `call'
railties (7.0.5) lib/rails/engine.rb:530:in `call'
puma (6.3.0) lib/puma/configuration.rb:270:in `call'
puma (6.3.0) lib/puma/request.rb:100:in `block in handle_request'
puma (6.3.0) lib/puma/thread_pool.rb:344:in `with_force_shutdown'
puma (6.3.0) lib/puma/request.rb:99:in `handle_request'
puma (6.3.0) lib/puma/server.rb:443:in `process_client'
puma (6.3.0) lib/puma/server.rb:245:in `block in run'```

Cannot manually generate an access token and refresh token

I am trying to create a token for my users factory to use in rspec tests. This is the factory code:

FactoryBot.define do
  factory :user do
    email { '[email protected]' }
    password { 'password1234' }

    trait :with_token do
      after(:create) do |user|
        Devise::Api::Token.create!(resource_owner: user)
      end
    end
  end
end

This is the error which is returned:

  1) V1::Organisations API behaves like API Resource GET #index returns a list of resources
     Failure/Error: Devise::Api::Token.create!(resource_owner: user)

     ActiveRecord::RecordInvalid:
       Validation failed: Access token can't be blank, Refresh token can't be blank, Expires in can't be blank, Expires in is not a number
     Shared Example Group: "API Resource" called from ./spec/requests/v1/organisations_spec.rb:8
     # ./spec/factories/users.rb:9:in `block (4 levels) in <main>'
     # ./spec/support/api_resource_shared_examples.rb:15:in `block (2 levels) in <main>'
     # ./spec/support/api_resource_shared_examples.rb:19:in `block (3 levels) in <main>'

I get the same error when trying to generate a token for a user in the rails console like this:

u = User.first

Devise::Api::Token.create!(resource_owner: u)

Am I creating the token incorrectly?

EDIT:

I am now creating the token like this:

create_token_service = Devise::Api::TokensService::Create.new(resource_owner: user, previous_refresh_token: nil)
create_token_service.call

This code successfully creates the token but Devise::Api::Token.where(resource_owner: user).first does not return this newly created token. Instead it returns an old token.

Another edit: Devise::Api::Token.where(resource_owner: user).reload.last loads the new token.

Confirmation email redirect to a certain host

Greetings.

I implemented devise's email confirmation on my app, which is an api only app and I also use devise-api in order to bring it to life.
The problem is when I confirm the account, it goes to localhost:3001/users/sing_in which is not there. I just want it to send my user back to the index page of my site. I am using this method:

class ConfirmationsController < Devise::ConfirmationsController

    def new
        super
      end
    
      def create
        super
      end
    
      def show
        self.resource = resource_class.confirm_by_token(params[:confirmation_token])
    
        if resource.errors.empty?
          set_flash_message(:notice, :confirmed) if is_navigational_format?
          sign_in(resource_name, resource)
          respond_with_navigational(resource){ redirect_to('https://example.com/page', allow_other_host: true) }
        else
          false
        end
      end

end

But as I said earlier, it goes to /users/sign_in to my app which does not exist.

null resource_owner_id when calling `/users/tokens/sign_up`

gem "rails", "7.0.3.1"
gem "devise", "~> 4.9.2"
gem "devise-api", "~> 0.1.1"

After following the instructions in README, when calling:

curl --location --request POST 'http://127.0.0.1:3000/users/tokens/sign_up' \
--header 'Content-Type: application/json' \
--data-raw '{
    "email": "[email protected]",
    "password": "123456"
}'

I get the following error:

ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR:  null value in column "resource_owner_id" of relation "devise_api_tokens" violates not-null constraint
DETAIL:  Failing row contains (16, User, null, yFGekCPsECmhuyYCFzxUSwbgrso8zTTTjfoaszJ7s8Mx_VJSq_64njNrsfc-, sW5JeuBM1eAZG_Y939eoo49ETxTd6yzypyaw7j-oSMjaRadxoaC3yx7Ra4So, 3600, null, null, 2023-04-06 15:18:25.860126, 2023-04-06 15:18:25.860126).
):

activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `exec_params'
activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql_adapter.rb:768:in `block (2 levels) in exec_no_cache'
activesupport (7.0.3.1) lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
activesupport (7.0.3.1) lib/active_support/dependencies/interlock.rb:41:in `permit_concurrent_loads'
activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql_adapter.rb:767:in `block in exec_no_cache'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract_adapter.rb:765:in `block in log'
activesupport (7.0.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract_adapter.rb:756:in `log'
activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql_adapter.rb:766:in `exec_no_cache'
activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql_adapter.rb:745:in `execute_and_clear'
activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql/database_statements.rb:54:in `exec_query'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/database_statements.rb:132:in `exec_insert'
activerecord (7.0.3.1) lib/active_record/connection_adapters/postgresql/database_statements.rb:92:in `exec_insert'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/database_statements.rb:167:in `insert'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/query_cache.rb:22:in `insert'
activerecord (7.0.3.1) lib/active_record/persistence.rb:496:in `_insert_record'
activerecord (7.0.3.1) lib/active_record/persistence.rb:1096:in `_create_record'
activerecord (7.0.3.1) lib/active_record/counter_cache.rb:166:in `_create_record'
activerecord (7.0.3.1) lib/active_record/locking/optimistic.rb:79:in `_create_record'
activerecord (7.0.3.1) lib/active_record/attribute_methods/dirty.rb:222:in `_create_record'
activerecord (7.0.3.1) lib/active_record/callbacks.rb:461:in `block in _create_record'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:107:in `run_callbacks'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:929:in `_run_create_callbacks'
activerecord (7.0.3.1) lib/active_record/callbacks.rb:461:in `_create_record'
activerecord (7.0.3.1) lib/active_record/timestamp.rb:108:in `_create_record'
activerecord (7.0.3.1) lib/active_record/persistence.rb:1067:in `create_or_update'
activerecord (7.0.3.1) lib/active_record/callbacks.rb:457:in `block in create_or_update'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:118:in `block in run_callbacks'
activerecord (7.0.3.1) lib/active_record/autosave_association.rb:370:in `around_save_collection_association'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:127:in `block in run_callbacks'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:138:in `run_callbacks'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:929:in `_run_save_callbacks'
activerecord (7.0.3.1) lib/active_record/callbacks.rb:457:in `create_or_update'
activerecord (7.0.3.1) lib/active_record/timestamp.rb:126:in `create_or_update'
activerecord (7.0.3.1) lib/active_record/persistence.rb:615:in `save'
activerecord (7.0.3.1) lib/active_record/validations.rb:47:in `save'
activerecord (7.0.3.1) lib/active_record/transactions.rb:298:in `block in save'
activerecord (7.0.3.1) lib/active_record/transactions.rb:354:in `block in with_transaction_returning_status'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/database_statements.rb:314:in `transaction'
activerecord (7.0.3.1) lib/active_record/transactions.rb:350:in `with_transaction_returning_status'
activerecord (7.0.3.1) lib/active_record/transactions.rb:298:in `save'
activerecord (7.0.3.1) lib/active_record/suppressor.rb:50:in `save'
devise-api (0.1.1) app/services/devise/api/tokens_service/create.rb:29:in `create_devise_api_token'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `block in create_devise_api_token'
dry-monads (1.6.0) lib/dry/monads/do/mixin.rb:40:in `call'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `create_devise_api_token'
devise-api (0.1.1) app/services/devise/api/tokens_service/create.rb:13:in `call'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `block in call'
dry-monads (1.6.0) lib/dry/monads/do/mixin.rb:40:in `call'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `call'
devise-api (0.1.1) app/services/devise/api/resource_owner_service/sign_up.rb:31:in `call_create_devise_api_token_service'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `block in call_create_devise_api_token_service'
dry-monads (1.6.0) lib/dry/monads/do/mixin.rb:40:in `call'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `call_create_devise_api_token_service'
devise-api (0.1.1) app/services/devise/api/resource_owner_service/sign_up.rb:14:in `block in call'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/transaction.rb:319:in `block in within_new_transaction'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `handle_interrupt'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:25:in `block in synchronize'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `handle_interrupt'
activesupport (7.0.3.1) lib/active_support/concurrency/load_interlock_aware_monitor.rb:21:in `synchronize'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/transaction.rb:317:in `within_new_transaction'
activerecord (7.0.3.1) lib/active_record/connection_adapters/abstract/database_statements.rb:316:in `transaction'
activerecord (7.0.3.1) lib/active_record/transactions.rb:209:in `transaction'
devise-api (0.1.1) app/services/devise/api/resource_owner_service/sign_up.rb:11:in `call'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `block in call'
dry-monads (1.6.0) lib/dry/monads/do/mixin.rb:40:in `call'
dry-monads (1.6.0) lib/dry/monads/do.rb:131:in `call'
devise-api (0.1.1) app/controllers/devise/api/tokens_controller.rb:17:in `sign_up'
actionpack (7.0.3.1) lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
actionpack (7.0.3.1) lib/abstract_controller/base.rb:215:in `process_action'
actionpack (7.0.3.1) lib/action_controller/metal/rendering.rb:53:in `process_action'
actionpack (7.0.3.1) lib/abstract_controller/callbacks.rb:234:in `block in process_action'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:118:in `block in run_callbacks'
actiontext (7.0.3.1) lib/action_text/rendering.rb:20:in `with_renderer'
actiontext (7.0.3.1) lib/action_text/engine.rb:69:in `block (4 levels) in <class:Engine>'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:127:in `instance_exec'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:127:in `block in run_callbacks'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:138:in `run_callbacks'
actionpack (7.0.3.1) lib/abstract_controller/callbacks.rb:233:in `process_action'
actionpack (7.0.3.1) lib/action_controller/metal/rescue.rb:22:in `process_action'
actionpack (7.0.3.1) lib/action_controller/metal/instrumentation.rb:67:in `block in process_action'
activesupport (7.0.3.1) lib/active_support/notifications.rb:206:in `block in instrument'
activesupport (7.0.3.1) lib/active_support/notifications/instrumenter.rb:24:in `instrument'
activesupport (7.0.3.1) lib/active_support/notifications.rb:206:in `instrument'
actionpack (7.0.3.1) lib/action_controller/metal/instrumentation.rb:66:in `process_action'
actionpack (7.0.3.1) lib/action_controller/metal/params_wrapper.rb:259:in `process_action'
activerecord (7.0.3.1) lib/active_record/railties/controller_runtime.rb:27:in `process_action'
actionpack (7.0.3.1) lib/abstract_controller/base.rb:151:in `process'
actionview (7.0.3.1) lib/action_view/rendering.rb:39:in `process'
actionpack (7.0.3.1) lib/action_controller/metal.rb:188:in `dispatch'
actionpack (7.0.3.1) lib/action_controller/metal.rb:251:in `dispatch'
actionpack (7.0.3.1) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
actionpack (7.0.3.1) lib/action_dispatch/routing/route_set.rb:32:in `serve'
actionpack (7.0.3.1) lib/action_dispatch/routing/mapper.rb:18:in `block in <class:Constraints>'
actionpack (7.0.3.1) lib/action_dispatch/routing/mapper.rb:48:in `serve'
actionpack (7.0.3.1) lib/action_dispatch/journey/router.rb:50:in `block in serve'
actionpack (7.0.3.1) lib/action_dispatch/journey/router.rb:32:in `each'
actionpack (7.0.3.1) lib/action_dispatch/journey/router.rb:32:in `serve'
actionpack (7.0.3.1) lib/action_dispatch/routing/route_set.rb:852:in `call'
omniauth (1.9.1) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.1) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.1) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.1) lib/omniauth/strategy.rb:169:in `call'
warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
warden (1.2.9) lib/warden/manager.rb:34:in `catch'
warden (1.2.9) lib/warden/manager.rb:34:in `call'
rack (2.2.6.4) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.6.4) lib/rack/etag.rb:27:in `call'
rack (2.2.6.4) lib/rack/conditional_get.rb:40:in `call'
rack (2.2.6.4) lib/rack/head.rb:12:in `call'
actionpack (7.0.3.1) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
actionpack (7.0.3.1) lib/action_dispatch/http/content_security_policy.rb:36:in `call'
rack (2.2.6.4) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.6.4) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/cookies.rb:697:in `call'
activerecord (7.0.3.1) lib/active_record/migration.rb:603:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.3.1) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.3.1) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
sentry-rails (5.4.1) lib/sentry/rails/rescued_exception_interceptor.rb:12:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
sentry-ruby (5.4.1) lib/sentry/rack/capture_exceptions.rb:28:in `block (2 levels) in call'
sentry-ruby (5.4.1) lib/sentry/hub.rb:199:in `with_session_tracking'
sentry-ruby (5.4.1) lib/sentry-ruby.rb:372:in `with_session_tracking'
sentry-ruby (5.4.1) lib/sentry/rack/capture_exceptions.rb:19:in `block in call'
sentry-ruby (5.4.1) lib/sentry/hub.rb:59:in `with_scope'
sentry-ruby (5.4.1) lib/sentry-ruby.rb:352:in `with_scope'
sentry-ruby (5.4.1) lib/sentry/rack/capture_exceptions.rb:18:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/show_exceptions.rb:26:in `call'
railties (7.0.3.1) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.3.1) lib/rails/rack/logger.rb:25:in `block in call'
activesupport (7.0.3.1) lib/active_support/tagged_logging.rb:114:in `block in tagged'
activesupport (7.0.3.1) lib/active_support/tagged_logging.rb:38:in `tagged'
activesupport (7.0.3.1) lib/active_support/tagged_logging.rb:114:in `tagged'
railties (7.0.3.1) lib/rails/rack/logger.rb:25:in `call'
sprockets-rails (3.4.2) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.6.4) lib/rack/method_override.rb:24:in `call'
rack (2.2.6.4) lib/rack/runtime.rb:22:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.6.4) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.3.1) lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
rack-cors (1.1.1) lib/rack/cors.rb:100:in `call'
shakapacker (6.5.0) lib/webpacker/dev_server_proxy.rb:25:in `perform_request'
rack-proxy (0.7.2) lib/rack/proxy.rb:67:in `call'
railties (7.0.3.1) lib/rails/engine.rb:530:in `call'
puma (5.6.4) lib/puma/configuration.rb:252:in `call'
puma (5.6.4) lib/puma/request.rb:77:in `block in handle_request'
puma (5.6.4) lib/puma/thread_pool.rb:340:in `with_force_shutdown'
puma (5.6.4) lib/puma/request.rb:76:in `handle_request'
puma (5.6.4) lib/puma/server.rb:441:in `process_client'
puma (5.6.4) lib/puma/thread_pool.rb:147:in `block in spawn_thread'

With some debugging I confirmed that the devise_api_token created in https://github.com/nejdetkadir/devise-api/blob/main/app/services/devise/api/tokens_service/create.rb#L26 has resource_owner_id set to null. What should I check to be successful in troubleshooting this?

uninitialized constant Devise::Api::Responses::ErrorResponseDecorator (NameError)

I'm using the instructions in the Readme to override the default response but when I prepend the decorator to the response class I get the following error when I start the rails server:

โฏ rails s
=> Booting Puma
=> Rails 7.0.6 application starting in development
=> Run `bin/rails server --help` for more startup options
Exiting
/Users/derek/CodeRepos/project/config/initializers/devise.rb:358:in `<main>': uninitialized constant Devise::Api::Responses::ErrorResponseDecorator (NameError)

Devise::Api::Responses::ErrorResponse.prepend Devise::Api::Responses::ErrorResponseDecorator

This is my lib/devise/api/responses/error_response_decorator.rb:

module Devise::Api::Responses::ErrorResponseDecorator
  def body
    if error_description
      {
        errors: [
          {
            status: "401",
            title: error,
            detail: error_description.join(" "),
            source: { pointer: "/data/attributes/token" }
          }
        ]
      }
    end
  end
end

This is the line causing an issue, in the Devise initialiser added after the config block is closed:

Devise::Api::Responses::ErrorResponse.prepend Devise::Api::Responses::ErrorResponseDecorator

ActiveRecord::NotNullViolation (PG::NotNullViolation: ERROR: null value in column "resource_owner_id" of relation "devise_api_tokens" violates not-null constraint

Hello everyone, I have an issue setting up this gem, I follow the instructions and when I try to create a new user I got this error (see the title) the resource_owner_id is null, and if you can see the image attached, when the transaction starts the user is created, I will leave here my model and other things, any help I will really appreciate!

User Model:

Screenshot from 2023-03-27 20-04-58

Schema:

Screenshot from 2023-03-27 20-06-21

image

Error:

Screenshot from 2023-03-27 19-58-27
Screenshot from 2023-03-27 19-58-47

Access_Token & Refresh_Token expire at the same time

Hello, I've been trying to figure this out for the past couple of days. Before making any changes to my config/initializers/devise.rb file, It appears that the access_token defaults to an expiration value of 3600 (1 hour). To my understanding, the refresh_token expiration should be longer than the access_token in order for us to get a new access_token once it expires by way of the refresh token.

Today, I reviewed the Repo documentation and was happy to see I could in fact override these values. For a test, I changed applied the following config.

  config.api.configure do |api|
    # Access Token
    api.access_token.expires_in = 1.minute
    # Refresh Token
    api.refresh_token.enabled = true
    api.refresh_token.expires_in = 15.minutes

  end

I was hoping this would increase my test iteration time, allowing me to validate my new access_token logic. However, when testing this post login just after 1 mins, the response yield token expired. I am passing the refresh token to get a new access token and it should live longer than 1 min. I'm curious if anyone else has faced a similar issue, and if the source code itself may need updating to be able to appropriately extend these values independently.

please advise...

-Truman

Does token refresh work when the access token has expired?

Hi, I begin to use devise-api and I found it a great gem, thanks.

However, I do not understand how the refresh token works.

My configuration is like suggested, but I do not see any reference for refresh_token expiration: api.refresh_token.expires_in seems be the api.access_token.expires_in to me.

# ==> Configuration for :api
  config.api.configure do |api|

      # Access Token
      # access tokens. Access tokens are the credentials representing the authorization given to an application
      # api.access_token.expires_in = 2.hours
      api.access_token.expires_in = 5.seconds
      api.access_token.expires_in_infinite = ->(_resource_owner) { false }
      api.access_token.generator = ->(_resource_owner) { Devise.friendly_token(60) }

      # Refresh Token
      # Unlike access tokens, refresh tokens have a longer lifespan
      api.refresh_token.enabled = true
      api.refresh_token.expires_in = 1.week
      api.refresh_token.generator = ->(_resource_owner) { Devise.friendly_token(60) }
      api.refresh_token.expires_in_infinite = ->(_resource_owner) { false }

      # Authorization
      api.authorization.key = 'Authorization'
      api.authorization.scheme = 'Bearer'
      api.authorization.location = :both # :header or :params or :both
      api.authorization.params_key = 'access_token'

      # Base classes
      api.base_token_model = 'Devise::Api::Token'
      api.base_controller = '::DeviseController'

      # After successful callbacks
      api.after_successful_sign_in = ->(_resource_owner, _token, _request) { }
      api.after_successful_sign_up = ->(_resource_owner, _token, _request) { }
      api.after_successful_refresh = ->(_resource_owner, _token, _request) { }
      api.after_successful_revoke = ->(_resource_owner, _token, _request) { }

      # Before callbacks
      api.before_sign_in = ->(_params, _request, _resource_class) { }
      api.before_sign_up = ->(_params, _request, _resource_class) { }
      api.before_refresh = ->(_params, _request, _resource_class) { }
      # api.before_revoke = ->(_params, _request, _resource_class) { }
    end

Thus, to test it, I decrese the access_token expiration to 5 seconds, and it got the record at database in the table devise_api_tokens

// users/tokens/sign_in
{
    "refresh_token": "arvMhr-aTiBPqv53N1B3n21B_KsJbnXCdZTDM3E2HxWoVoHihpwy-kMRyzNp",
    "expires_in": 5,
    "token_type": "Bearer",
    "resource_owner": {
        "id": 1,
        "email": "[email protected]",
        "created_at": "2023-03-29T07:27:40.783Z",
        "updated_at": "2023-03-29T07:28:31.340Z"
    },
    "access_token": "q-H4PeyB7PnVAusBsUbs2c1_y8kPb9xPdzUWxzGkTAZ9wcxrEtfTAzB8B9QH"
}

However, when I go to refresh this token , I got "token has expired":

curl --location --request POST 'http://localhost:3000/api/v1/users/tokens/refresh' \
--header 'Authorization: Bearer arvMhr-aTiBPqv53N1B3n21B_KsJbnXCdZTDM3E2HxWoVoHihpwy-kMRyzNp'
// users/tokens/refresh
{
    "error": "expired_token",
    "error_description": [
        "Token has expired"
    ]
}

Finally, It seems to be get the same reference of token expiration than access token. But on your code I found this reference :

image

And now , I am lost. Could someone help me, please?

Incompatible with Mongoid ORM

Devise.setup do |config|
  config.mailer_sender = '[email protected]'
  require 'devise/orm/mongoid'
  config.case_insensitive_keys = [:email]
  config.strip_whitespace_keys = [:email]
  config.skip_session_storage = [:http_auth]
  config.reconfirmable = true
  config.expire_all_remember_me_on_sign_out = true
  config.responder.error_status = :unprocessable_entity
  config.responder.redirect_status = :see_other
end

ActiveRecord::ConnectionNotEstablished at /api/v1/users/tokens/sign_in

No connection pool for 'ActiveRecord::Base' found.

To access an interactive console with this error, point your browser to: /__better_errors

activerecord (7.0.8) lib/active_record/connection_adapters/abstract/connection_handler.rb, line 208

  203               message = "No connection pool for '#{spec_name}' found for the '#{role}' role."
  204             else
  205               message = "No connection pool for '#{spec_name}' found."
  206             end
  207   
> 208             raise ConnectionNotEstablished, message
  209           end
  210   
  211           pool.connection
  212         end
  213   

App backtrace

Full backtrace

  • activerecord (7.0.8) lib/active_record/connection_adapters/abstract/connection_handler.rb:208:in `retrieve_connection'
  • activerecord (7.0.8) lib/active_record/connection_handling.rb:313:in `retrieve_connection'
  • activerecord (7.0.8) lib/active_record/connection_handling.rb:280:in `connection'
  • activerecord (7.0.8) lib/active_record/model_schema.rb:407:in `table_exists?'
  • activerecord (7.0.8) lib/active_record/attribute_methods.rb:163:in `attribute_names'
  • actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:118:in `block in include'
  • /usr/local/lib/ruby/3.2.0/mutex_m.rb:79:in `mu_synchronize'
  • actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:112:in `include'
  • actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:278:in `_extract_parameters'
  • actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:274:in `_wrap_parameters'
  • actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:300:in `_perform_parameter_wrapping'
  • actionpack (7.0.8) lib/action_controller/metal/params_wrapper.rb:258:in `process_action'
  • mongoid (8.1.4) lib/mongoid/railties/controller_runtime.rb:21:in `process_action'
  • actionpack (7.0.8) lib/abstract_controller/base.rb:151:in `process'
  • actionview (7.0.8) lib/action_view/rendering.rb:39:in `process'
  • actionpack (7.0.8) lib/action_controller/metal.rb:188:in `dispatch'
  • actionpack (7.0.8) lib/action_controller/metal.rb:251:in `dispatch'
  • actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:49:in `dispatch'
  • actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:32:in `serve'
  • actionpack (7.0.8) lib/action_dispatch/routing/mapper.rb:18:in `block in class:Constraints'
  • actionpack (7.0.8) lib/action_dispatch/routing/mapper.rb:48:in `serve'
  • actionpack (7.0.8) lib/action_dispatch/journey/router.rb:50:in `block in serve'
  • actionpack (7.0.8) lib/action_dispatch/journey/router.rb:32:in `serve'
  • actionpack (7.0.8) lib/action_dispatch/routing/route_set.rb:852:in `call'
  • mongo (2.19.3) lib/mongo/query_cache.rb:278:in `block in call'
  • mongo (2.19.3) lib/mongo/query_cache.rb:52:in `cache'
  • mongo (2.19.3) lib/mongo/query_cache.rb:277:in `call'
  • warden (1.2.9) lib/warden/manager.rb:36:in `block in call'
  • warden (1.2.9) lib/warden/manager.rb:34:in `call'
  • rack (2.2.8) lib/rack/tempfile_reaper.rb:15:in `call'
  • rack (2.2.8) lib/rack/etag.rb:27:in `call'
  • rack (2.2.8) lib/rack/conditional_get.rb:40:in `call'
  • rack (2.2.8) lib/rack/head.rb:12:in `call'
  • actionpack (7.0.8) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
  • actionpack (7.0.8) lib/action_dispatch/http/content_security_policy.rb:36:in `call'
  • rack (2.2.8) lib/rack/session/abstract/id.rb:266:in `context'
  • rack (2.2.8) lib/rack/session/abstract/id.rb:260:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/cookies.rb:704:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
  • activesupport (7.0.8) lib/active_support/callbacks.rb:99:in `run_callbacks'
  • actionpack (7.0.8) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/executor.rb:14:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
  • better_errors (2.10.1) lib/better_errors/middleware.rb:87:in `protected_app_call'
  • better_errors (2.10.1) lib/better_errors/middleware.rb:82:in `better_errors_call'
  • better_errors (2.10.1) lib/better_errors/middleware.rb:60:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
  • web-console (4.2.1) lib/web_console/middleware.rb:132:in `call_app'
  • web-console (4.2.1) lib/web_console/middleware.rb:28:in `block in call'
  • web-console (4.2.1) lib/web_console/middleware.rb:17:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'
  • railties (7.0.8) lib/rails/rack/logger.rb:40:in `call_app'
  • railties (7.0.8) lib/rails/rack/logger.rb:25:in `block in call'
  • activesupport (7.0.8) lib/active_support/tagged_logging.rb:99:in `block in tagged'
  • activesupport (7.0.8) lib/active_support/tagged_logging.rb:37:in `tagged'
  • activesupport (7.0.8) lib/active_support/tagged_logging.rb:99:in `tagged'
  • railties (7.0.8) lib/rails/rack/logger.rb:25:in `call'
  • sprockets-rails (3.4.2) lib/sprockets/rails/quiet_assets.rb:13:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
  • request_store (1.5.1) lib/request_store/middleware.rb:19:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/request_id.rb:26:in `call'
  • rack (2.2.8) lib/rack/method_override.rb:24:in `call'
  • rack (2.2.8) lib/rack/runtime.rb:22:in `call'
  • activesupport (7.0.8) lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/server_timing.rb:61:in `block in call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/server_timing.rb:26:in `collect_events'
  • actionpack (7.0.8) lib/action_dispatch/middleware/server_timing.rb:60:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/executor.rb:14:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/static.rb:23:in `call'
  • rack (2.2.8) lib/rack/sendfile.rb:110:in `call'
  • actionpack (7.0.8) lib/action_dispatch/middleware/host_authorization.rb:138:in `call'
  • rack-cors (2.0.1) lib/rack/cors.rb:102:in `call'
  • railties (7.0.8) lib/rails/engine.rb:530:in `call'
  • puma (6.4.2) lib/puma/configuration.rb:272:in `call'
  • puma (6.4.2) lib/puma/request.rb:100:in `block in handle_request'
  • puma (6.4.2) lib/puma/thread_pool.rb:378:in `with_force_shutdown'
  • puma (6.4.2) lib/puma/request.rb:99:in `handle_request'
  • puma (6.4.2) lib/puma/server.rb:464:in `process_client'
  • puma (6.4.2) lib/puma/server.rb:245:in `block in run'
  • puma (6.4.2) lib/puma/thread_pool.rb:155:in `block in spawn_thread'

resource_owner_id is null on login

What

This error occurs when you try to login

{
    "status": 500,
    "error": "Internal Server Error",
    "exception": "#<ActiveRecord::NotNullViolation:\"PG::NotNullViolation: ERROR:  null value in column \\\"resource_owner_id\\\" of relation \\\"devise_api_tokens\\\" violates not-null constraint\\nDETAIL:  Failing row contains (1, User, null, aVVZU8x26XqyetX4LWXSc6ovS5Ri2P-27yzPDyb_PwAvw7UUSzkHboLMxEyJ, SjVyHn43yomfgMbqQGHmMFAHmg8sV4xCCymTFcB2kX4HA2dn-ffzDux5XM5f, 3600, null, null, 2023-05-29 13:02:32.346515, 2023-05-29 13:02:32.346515).\\n\">",

Why

Because the resource_owner_id is null and database migration has null: false

t.belongs_to :resource_owner, null: false, type: :uuid, polymorphic: true, index: true

Additional Info

This is what happens if I remove the null: false from the migration

[
  {
    "id": 1,
    "resource_owner_type": "User",
    "resource_owner_id": null,
    "access_token": "JbxfzM9-NVEx1SSiz_Y616cQtA36hMHQsqe_yxSthqRQkzzZbycZdx3hF8tZ",
    "refresh_token": "xuj_jozE1gA4py886MVSp83-dapP4g3VhzyusVyCyra9v-ecsi5YGSBDhPzM",
    "expires_in": 3600,
    "revoked_at": null,
    "previous_refresh_token": null,
    "created_at": "2023-05-29 13:08:16.431017",
    "updated_at": "2023-05-29 13:08:16.431017"
  }
]

Need to know what in Rails 7 resource_owner_id is coming as null. The Users table is "users" the standard table.

route.rb

  devise_for :users
  resources :users

User Model

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable,
         :confirmable, :lockable, :timeoutable, :trackable,
         :api

The API response I get after login

{
    "token": "JbxfzM9-NVEx1SSiz_Y616cQtA36hMHQsqe_yxSthqRQkzzZbycZdx3hF8tZ",
    "refresh_token": "xuj_jozE1gA4py886MVSp83-dapP4g3VhzyusVyCyra9v-ecsi5YGSBDhPzM",
    "expires_in": 3600,
    "token_type": "Bearer",
    "resource_owner": {
        "id": 1,
        "email": "[email protected]",
        "created_at": "2023-05-29T13:08:10.694Z",
        "updated_at": "2023-05-29T13:08:16.449Z"
    }
}

However in the database "resource_owner_id" is null (if I remove not null in the migration)

omniauth-google-oauth2 and devise-api

Hey,

do you know if this works together? omniauth-google-oauth2 and devise-api

have some problems with the CERF token with api only ( at the moment not using devise-api)

ActiveRecord::NotNullViolation in Devise::Api::TokensController#sign_in

๐Ÿ‘‹ I wanted to give a try to this gem but when I try to sign_in I get this error:

ActiveRecord::NotNullViolation in Devise::Api::TokensController#sign_in
PG::NotNullViolation: ERROR: null value in column "resource_owner_id" of relation "devise_api_tokens" violates not-null constraint
DETAIL: Failing row contains (21, User, null, 8rUvzXixhsNeyypZBWjsm3-aQszFgrBKm2EngYsy1S24PGsYSFrwD6Cxh3Hu, KuxVpFjzq8vopMMzztR3f7i47LgsST33XL44tAzCVA19xCnxZGLztgHwdTDk, 3600, null, null, 2023-04-12 09:50:42.582888, 2023-04-12 09:50:42.582888).

I tried to debug with ChatGPT without success, I can't find where this ressource_owner_id got lost...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.