Skip to content

aarona/graphql_devise

 
 

Repository files navigation

GraphqlDevise

Build Status Gem Version

GraphQL interface on top of the Devise Token Auth (DTA) gem.

Installation

Add this line to your application's Gemfile:

gem 'graphql_devise'

And then execute:

$ bundle

Or install it yourself as:

$ gem install graphql_devise

Next, you need to run the generator:

$ rails generate graphql_devise:install

Graphql Devise generator will execute Devise and Devise Token Auth generators for you. These will make the required changes for the gems to work correctly. All configurations for Devise and Devise Token Auth are available, so you can read the docs there to customize your options. Configurations are done via initializer files as usual, one per gem.

The generator accepts 2 params: user_class and mount_path. The params will be used to mount the route in config/routes.rb. For instance the executing:

$ rails g graphql_devise:install Admin api/auth

Will do the following:

  • Execute Devise install generator
  • Execute Devise Token Auth install generator with Admin and api/auth as params
    • Find or create Admin model
    • Add devise modules to Admin model
    • Other changes that you can find here
  • Add the route to config/routes.rb
    • `mount_graphql_devise_for 'Admin', at: 'api/auth'

Admin could be any model name you are going to be using for authentication, and api/auth could be any mount path you would like to use for auth.

Mounting Routes manually

Routes can be added using the initializer or manually. You can add a route like this:

# config/routes.rb

Rails.application.routes.draw do
  mount_graphql_devise_for(
    'User',
    at: 'api/v1',
    authenticatable_type: Types::MyCustomUserType,
    operations: {
      login: Mutations::Login
    },
    skip: [:sign_up]
  )
end

Here are the options for the mount method:

  1. at: Route where the GraphQL schema will be mounted on the Rails server. In this example your API will have these two routes: POST /api/v1/graphql_auth and GET /api/v1/graphql_auth. If this option is not specified, the schema will be mounted at /graphql_auth.
  2. operations: Specifying this is optional. Here you can override default behavior by specifying your own mutations and queries for every GraphQL operation. Check available operations in this file mutations and queries. All mutations and queries are built so you can extend default behavior just by extending our default classes and yielding your customized code after calling super, example here.
  3. authenticatable_type: By default, the gem will add an authenticatable field to every mutation and an authenticatable type to every query. Gem will try to use Types::<model>Type by default, so in our example you could define Types::UserType and every query and mutation will use it. But, you can override this type with this option like in the example.
  4. skip: An array of the operations that should not be available in the authentication schema. All these operations are symbols and should belong to the list of available operations in the gem.
  5. only: An array of the operations that should be available in the authentication schema. The skip and only options are mutually exclusive, an error will be raised if you pass both to the mount method.

Available Operations

The following is a list of the symbols you can provide to the operations, skip and only options of the mount method:

:login
:logout
:sign_up
:update_password
:send_password_reset
:confirm_account
:check_password_token

Configuring Model

Just like with Devise and DTA, you need to include a module in your authenticatable model, so with our example, your user model will have to look like this:

# app/models/user.rb

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

  # including after calling the `devise` method is important.
  include GraphqlDevise::Concerns::Model
end

The install generator can do this for you if you specify the user_class option. See Installation for details.

Customizing Email Templates

The approach of this gem is a bit different from DeviseTokenAuth. We have placed our templates in app/views/graphql_devise/mailer, so if you want to change them, place yours on the same dir structure on your Rails project. You can customize these two templates:

  1. app/views/graphql_devise/mailer/confirmation_instructions.html.erb
  2. app/views/graphql_devise/mailer/reset_password_instructions.html.erb

The main reason for this difference is just to make it easier to have both Standard Devise and this gem running at the same time. Check these files to see the available helper methods you can use in your views.

Authenticating Controller Actions

Just like with Devise or DTA, you will need to authenticate users in your controllers. For this you need to call authenticate_<model>! in a before_action hook of your controller. In our example our model is User, so it would look like this:

# app/controllers/my_controller.rb

class MyController < ApplicationController
  before_action :authenticate_user!

  def my_action
    render json: { current_user: current_user }
  end
end

The install generator can do this for you because it executes DTA installer. See Installation for details.

Making Requests

Here is a list of the available mutations and queries assuming your mounted model is User.

Mutations

  1. userLogin(email: String!, password: String!): UserLoginPayload

  2. userLogout: UserLogoutPayload

  3. userSignUp(email: String!, password: String!, passwordConfirmation: String!, confirmSuccessUrl: String): UserSignUpPayload

    The parameter confirmSuccessUrl is optional unless you are using the confirmable plugin from Devise in your resource's model. If you have confirmable set up, you will have to provide it unless you have config.default_confirm_success_url set in config/initializers/devise_token_auth.rb.

  4. userUpdatePassword(password: String!, passwordConfirmation: String!, currentPassword: String): UserUpdatePasswordPayload

    The parameter currentPassword is optional if you have config.check_current_password_before_update set to false (disabled by default) or the resource model supports the recoverable Devise plugin and the resource's allow_password_change attribute is set to true.

  5. userSendResetPassword(email: String!, redirectUrl: String!): UserSendReserPasswordPayload

  6. userResendConfirmation(email: String!, redirectUrl: String!): UserResendConfirmationPayload

    The UserResendConfirmationPayload will return the authenticatable resource that was sent the confirmation instructions but also has a message: String! that can be used to notify a user what to do after the instructions were sent to them

Queries

  1. userConfirmAccount(confirmationToken: String!, redirectUrl: String!): User
  2. userCheckPasswordToken(resetPasswordToken: String!, redirectUrl: String): User

The reason for having 2 queries is that these 2 are going to be accessed when clicking on the confirmation and reset password email urls. There is no limitation for making mutation requests using the GET method on the Rails side, but looks like there might be a limitation on the Apollo Client.

We will continue to build better docs for the gem after this first release, but in the mean time you can use our specs to better understand how to use the gem. Also, the dummy app used in our specs will give you a clear idea on how to configure the gem on your Rails application.

Using Alongside Standard Devise

The DeviseTokenAuth gem allows experimental use of the standard Devise gem to be configured at the same time, for more information you can check this answer here.

This gem supports the same and should be easier to handle email templates due to the fact we don't override standard Devise templates.

Future Work

We will continue to improve the gem and add better docs.

  1. Add mount option that will create a separate schema for the mounted resource.
  2. Make sure this gem can correctly work alongside DTA and the original Devise gem.
  3. Improve DOCS.
  4. Add support for unlockable and other Devise modules.
  5. Add feature specs for confirm account and reset password flows.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/graphql-devise/graphql_devise.

License

The gem is available as open source under the terms of the MIT License.

About

GraphQL interface on top devise_token_auth

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 98.9%
  • Other 1.1%