{"id":13546047,"url":"https://github.com/nejdetkadir/devise-api","last_synced_at":"2025-04-07T21:09:41.760Z","repository":{"id":98152533,"uuid":"586673826","full_name":"nejdetkadir/devise-api","owner":"nejdetkadir","description":"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","archived":false,"fork":false,"pushed_at":"2024-12-12T10:06:04.000Z","size":87,"stargazers_count":166,"open_issues_count":1,"forks_count":29,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-31T20:05:44.754Z","etag":null,"topics":["devise","devise-api","devise-api-authenticatable","devise-gem-extension","devise-jwt","devise-oauth","devise-token-auth","devise-tokens","rails","rails-api","rails-api-backend","rails-gem"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nejdetkadir.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-08T23:42:14.000Z","updated_at":"2025-03-27T16:31:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"d48eb6ac-fcd5-411f-8026-d4bbbff33850","html_url":"https://github.com/nejdetkadir/devise-api","commit_stats":{"total_commits":23,"total_committers":8,"mean_commits":2.875,"dds":0.4347826086956522,"last_synced_commit":"cb55641b96a086183dcc20544de7e9d8c382cb9d"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejdetkadir%2Fdevise-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejdetkadir%2Fdevise-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejdetkadir%2Fdevise-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nejdetkadir%2Fdevise-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nejdetkadir","download_url":"https://codeload.github.com/nejdetkadir/devise-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247730068,"owners_count":20986404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["devise","devise-api","devise-api-authenticatable","devise-gem-extension","devise-jwt","devise-oauth","devise-token-auth","devise-tokens","rails","rails-api","rails-api-backend","rails-gem"],"created_at":"2024-08-01T12:00:30.551Z","updated_at":"2025-04-07T21:09:41.744Z","avatar_url":"https://github.com/nejdetkadir.png","language":"Ruby","funding_links":[],"categories":["Ruby","Authentication"],"sub_categories":[],"readme":"[![Gem Version](https://badge.fury.io/rb/devise-api.svg)](https://badge.fury.io/rb/devise-api)\n![test](https://github.com/nejdetkadir/devise-api/actions/workflows/test.yml/badge.svg?branch=main)\n![rubocop](https://github.com/nejdetkadir/devise-api/actions/workflows/rubocop.yml/badge.svg?branch=main)\n[![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop)\n![Ruby Version](https://img.shields.io/badge/ruby_version-\u003e=_2.7.0-blue.svg)\n\n# Devise API\nThe 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. It can be installed by adding the gem to your Gemfile, running migrations, and adding the :api module to your devise model. The gem is fully configurable, allowing you to set things like token expiration times and token generators.\n\nHere's how it works:\n\n- When a user logs in to your Rails application, the `devise-api` gem generates an access token and a refresh token.\n- The access token is included in the API request headers and is used to authenticate the user on each subsequent request.\n- The refresh token is stored on the client side (e.g. in a browser cookie or on a mobile device) and is used to obtain a new access token when the original access token expires.\n- This allows the user to remain logged in and make API requests without having to constantly re-enter their login credentials.\n\nOverall, the `devise-api` gem is a useful tool for adding secure authentication to your Ruby on Rails application.\n\n## Installation\n\nInstall the gem and add to the application's Gemfile by executing:\n```bash\n$ bundle add devise-api\n```\n\nOr add the following line to the application's Gemfile:\n```ruby\ngem 'devise-api', github: 'nejdetkadir/devise-api', branch: 'main'\n```\n\nIf bundler is not being used to manage dependencies, install the gem by executing:\n```bash\ngem install devise-api\n```\n\nAfter that, you need to generate relevant migrations and locales by executing:\n```bash\n$ rails generate devise_api:install\n```\n\nThis will introduce two changes:\n- Locale files in `config/locales/devise_api.en.yml`\n- Migration file in `db/migrate` to create devise api tokens table\n\nNow you're ready to run the migrations:\n```bash\n$ rails db:migrate\n```\n\nFinally, you need to add `:api` module to your devise model. For example:\n```ruby\nclass User \u003c ApplicationRecord\n  devise :database_authenticatable, \n         :registerable, \n         :recoverable,\n         :rememberable,\n         :validatable,\n         :api # \u003c--- Add this module\nend\n```\n\nYour user model is now ready to use `devise-api` gem. It will draw routes for token authenticatable and token refreshable.\n\n| Prefix | Verb | URI Pattern | Controller#Action        |\n|--------|------|------------|--------------------------|\n| revoke_user_tokens | POST | /users/tokens/revoke | devise/api/tokens#revoke |\n| refresh_user_tokens | POST | /users/tokens/refresh | devise/api/tokens#refresh |\n| sign_up_user_tokens | POST | /users/tokens/sign_up | devise/api/tokens#sign_up |\n| sign_in_user_tokens | POST | /users/tokens/sign_in | devise/api/tokens#sign_in |\n| info_user_tokens | GET | /users/tokens/info | devise/api/tokens#info |\n\n### You can look up the [example requests](#example-api-requests).\n\n## Configuration\n\n`devise-api` is a full configurable gem. You can configure it to your needs. Here is a basic usage example:\n\n```ruby\n# config/initializers/devise.rb\nDevise.setup do |config|\n  config.api.configure do |api|\n    # Access Token\n    api.access_token.expires_in = 1.hour\n    api.access_token.expires_in_infinite = -\u003e(_resource_owner) { false }\n    api.access_token.generator = -\u003e(_resource_owner) { Devise.friendly_token(60) }\n\n\n    # Refresh Token\n    api.refresh_token.enabled = true\n    api.refresh_token.expires_in = 1.week\n    api.refresh_token.generator = -\u003e(_resource_owner) { Devise.friendly_token(60) }\n    api.refresh_token.expires_in_infinite = -\u003e(_resource_owner) { false }\n\n    # Sign up\n    api.sign_up.enabled = true\n    api.sign_up.extra_fields = []\n\n    # Authorization\n    api.authorization.key = 'Authorization'\n    api.authorization.scheme = 'Bearer'\n    api.authorization.location = :both # :header or :params or :both\n    api.authorization.params_key = 'access_token'\n\n\n    # Base classes\n    api.base_token_model = 'Devise::Api::Token'\n    api.base_controller = '::DeviseController'\n\n\n    # After successful callbacks\n    api.after_successful_sign_in = -\u003e(_resource_owner, _token, _request) { }\n    api.after_successful_sign_up = -\u003e(_resource_owner, _token, _request) { }\n    api.after_successful_refresh = -\u003e(_resource_owner, _token, _request) { }\n    api.after_successful_revoke = -\u003e(_resource_owner, _token, _request) { }\n\n\n    # Before callbacks\n    api.before_sign_in = -\u003e(_params, _request, _resource_class) { }\n    api.before_sign_up = -\u003e(_params, _request, _resource_class) { }\n    api.before_refresh = -\u003e(_token_model, _request) { }\n    api.before_revoke = -\u003e(_token_model, _request) { }\n  end\nend\n```\n\n## Routes\n\nYou can configure the tokens routes with the orginally `devise_for` method. For example:\n```ruby\n# config/routes.rb\nRails.application.routes.draw do\n  devise_for :customers, \n             controllers: { tokens: 'customers/api/tokens' }\nend\n```\n\n## Usage\n`devise-api` module works with `:lockable` and `:confirmable` modules. It also works with `:trackable` module.\n\n`devise-api` provides a set of controllers and helpers to help you implement authentication in your Rails application. Here's a quick overview of the available controllers and helpers:\n\n- [Devise::Api::TokensController](https://github.com/nejdetkadir/devise-api/tree/main/app/controllers/devise/api/tokens_controller.rb) - This controller is responsible for generating access tokens and refresh tokens. It also provides actions for refreshing access tokens and revoking refresh tokens.\n\n- [Devise::Api::Token](https://github.com/nejdetkadir/devise-api/tree/main/lib/devise/api/token.rb) - This model is responsible for storing access tokens and refresh tokens in the database.\n\n- [Devise::Api::Responses::ErrorResponse](https://github.com/nejdetkadir/devise-api/tree/main/lib/devise/api/responses/error_response.rb) - This class is responsible for generating error responses. It also provides a set of error types and helpers to help you implement error responses in your Rails application.\n\n- [Devise::Api::Responses::TokenResponse](https://github.com/nejdetkadir/devise-api/tree/main/lib/devise/api/responses/token_response.rb) - This class is responsible for generating token responses. It also provides actions for generating access tokens and refresh tokens for each action.\n\n## Overriding Responses\nYou can prepend your decorators to the response classes to override the default responses. For example:\n```ruby\n# app/lib/devise/api/responses/token_response_decorator.rb\nmodule Devise::Api::Responses::TokenResponseDecorator\n  def body\n    return default_body.merge({ roles: resource_owner.roles })\n  end\nend\n```\n\nThen you need to load and prepend your decorator to the response class. For example:\n\n```ruby\n# config/initializers/devise.rb\nrequire 'devise/api/responses/token_response_decorator' # Either do this or autoload the lib directory\n\nDevise.setup do |config|\nend\n\nDevise::Api::Responses::TokenResponse.prepend Devise::Api::Responses::TokenResponseDecorator\n```\n\n## Using helpers\n`devise-api` provides a set of helpers to help you implement authentication in your Rails application. Here's a quick overview of the available helpers:\n\nExample:\n```ruby\n# app/controllers/api/v1/orders_controller.rb\nclass Api::V1::OrdersController \u003c YourBaseController\n  skip_before_action :verify_authenticity_token, raise: false  \n  before_action :authenticate_devise_api_token!\n\n  def index\n    render json: current_devise_api_user.orders, status: :ok\n  end\n\n  def show\n    devise_api_token = current_devise_api_token\n    render json: devise_api_token.resource_owner.orders.find(params[:id]), status: :ok\n  end\nend\n```\n\n## Using devise base services\n`devise-api` provides a set of base services to help you implement authentication in your Rails application. Here's a quick overview of the available services:\n\n- [Devise::Api::BaseService](https://github.com/nejdetkadir/devise-api/tree/main/app/services/devise/api/base_service.rb) - This service is useful for creating and updating resources. It is inherited by the following gems.\n- [dry-monads](https://dry-rb.org/gems/dry-monads)\n- [dry-types](https://dry-rb.org/gems/dry-types)\n- [dry-initializer](https://dry-rb.org/gems/dry-initializer)\n\nYou can create a service by inheriting the `Devise::Api::BaseService` class. For example:\n```ruby\n# app/services/devise/api/tokens_service/v2/create.rb\nmodule Devise::Api::TokensService::V2\n  class Create \u003c Devise::Api::BaseService\n    option :params, type: Types::Hash, reader: true\n    option :resource_class, type: Types::Class, reader: true\n\n    def call\n      ...\n\n      Success(resource)\n    end\n  end\nend\n```\n\nThen you can call the service in your controller. For example:\n```ruby\n# app/controllers/api/v1/tokens_controller.rb\nclass Api::V1::TokensController \u003c YourBaseController\n  skip_before_action :verify_authenticity_token, raise: false\n\n  def create\n    service = Devise::Api::TokensService::V2::Create.call(params: params, resource_class: Customer || resource_class)\n    if service.success?\n      render json: service.success, status: :created\n    else\n      render json: service.failure, status: :unprocessable_entity\n    end\n  end\nend\n```\n\n## Example API requests\n\n### Sign in\n```curl\ncurl --location --request POST 'http://127.0.0.1:3000/users/tokens/sign_in' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"email\": \"test@development.com\",\n    \"password\": \"123456\"\n}'\n```\n\n### Sign up\n```curl\ncurl --location --request POST 'http://127.0.0.1:3000/users/tokens/sign_up' \\\n--header 'Content-Type: application/json' \\\n--data-raw '{\n    \"email\": \"test@development.com\",\n    \"password\": \"123456\"\n}'\n```\n\n### Refresh token\n```curl\ncurl --location --request POST 'http://127.0.0.1:3000/users/tokens/refresh' \\\n--header 'Authorization: Bearer \u003crefresh_token\u003e'\n```\n\n### Revoke\n```curl\ncurl --location --request POST 'http://127.0.0.1:3000/users/tokens/revoke' \\\n--header 'Authorization: Bearer \u003caccess_token\u003e'\n```\n\n### Info\n```curl\ncurl --location --request GET 'http://127.0.0.1:3000/users/tokens/info' \\\n--header 'Authorization: Bearer \u003caccess_token\u003e'\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/nejdetkadir/devise-api. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/nejdetkadir/devise-api/blob/main/CODE_OF_CONDUCT.md).\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](LICENSE).\n\n## Code of Conduct\n\nEveryone interacting in the Devise::Api project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/nejdetkadir/devise-api/blob/main/CODE_OF_CONDUCT.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnejdetkadir%2Fdevise-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnejdetkadir%2Fdevise-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnejdetkadir%2Fdevise-api/lists"}