nejdetkadir / devise-api

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
MIT License
152 stars 22 forks source link

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

Closed 1gn0r4nd closed 1 year ago

1gn0r4nd commented 1 year ago

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 = 'please-change-me-at-config-initializers-devise@example.com'
  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

Hamdan85 commented 1 year ago

I think it shouldn't create a cookie since it is an API call don't you think!?

nejdetkadir commented 1 year ago

Hi @1gn0r4nd , we don't need to create cookie for API operations