DEV Community

Deepak Chauhan
Deepak Chauhan

Posted on

Devise and SendGrid integration into rails 6

Devise is a flexible production-ready authentication system supported in rails. The authentication system basically consists of three functionalities i.e. Signup, Login, and Logout. Further, in Signup, the password has to be a hashed password rather than a normal string and a confirmation link has to be sent on the registered email id for authenticating the user. In Login, a forget password functionality has to be there for recovery of password, and remember me functionality has to be there for saving credentials of the user in browser cookies for providing auto-filled credentials.

Instead of coding all these functionalities from scratch, use Devise. It is pre-equipped with all these functionalities and all of it can be accomplished by just installing the Devise gem. Devise is used extensively with so many functionalities that can be customized but in this article, I will only write about authenticating the registered user through a verification link. After registration, a verifying link has to be sent on the registered email id of the user On clicking it the user can verify himself.

HOW TO ACHIEVE THIS?

Well, we know that all these email operations are performed by the SMTP(Simple Mail Transfer Protocol) server. However, to set up an SMTP server for a beginner is quite back-breaking. Instead, we can use Sendgrid. SendGrid is a cloud-based SMTP provider that allows you to send email without having to maintain email servers. SendGrid manages all of the technical details and left you with just reaping the benefits of someone else’s effort.

LET’S CODE THIS

First, let’s include Devise gem and bundle install it in our gemfile.

gem 'devise'
Enter fullscreen mode Exit fullscreen mode

After bundle install. You need to run the generator:

rails generate devise:install
Enter fullscreen mode Exit fullscreen mode

The generator will install an initializer which describes ALL of Devise’s configuration options. By default, there are no views and models. You have to generate them. Let’s now generate a model User

rails generate devise User

You can also generate the corresponding Devise views.

rails generate devise:views users
Enter fullscreen mode Exit fullscreen mode

You can find a migration file that has been generated. Pull up that migration file and uncomment the 4 lines under confirmable:

t.string :confirmation_token
t.datetime :confirmed_at
t.datetime :confirmation_sent_at
t.string :unconfirmed_email
Enter fullscreen mode Exit fullscreen mode

Pull up the user.rb model file under app/models and in the line for devise, add in a:

:confirmable
Enter fullscreen mode Exit fullscreen mode

, after :registerable, entry Run your migration now to create the users table

rails db:migrate
Enter fullscreen mode Exit fullscreen mode

Devise will create some helpers to use inside your controllers and views. To set up a controller with user authentication, just add this before_action

before_action :authenticate_user!
Enter fullscreen mode Exit fullscreen mode

Now, Let’s hop onto sending email in production

for beginners, we are using Heroku as a production server. First, add your credit card details to your Heroku account. (Don’t worry this will not cost you a penny). Then enter in:

heroku addons:create sendgrid:starter
Enter fullscreen mode Exit fullscreen mode

This will add a SendGrid add-on to your deployed Heroku project. You can log in to your SendGrid account through this addon and in your SendGrid account menu you have to create an API key. After creating an API key, Now, we have to set the SendGrid API key credentials you created for Heroku.

heroku config:set SENDGRID_USERNAME=apikey
heroku config:set SENDGRID_PASSWORD=enterintheapikey
Enter fullscreen mode Exit fullscreen mode

In the SENDGRID_PASSWORD you have to enter the API key that you have created from SendGrid above Rails provides you to securely store your API credentials in your credentials.yml file. All the data inside this file is encrypted so security is ensured. The encrypted credentials.yml.enc file will be decrypted in production, using a key stored in the RAILS_MASTER_KEYenvironment variable For people using the VS Code as an editor. You can edit the credentials.yml file by enabling the edit mode as below

EDITOR='code --wait' rails credentials:edit
Enter fullscreen mode Exit fullscreen mode

After issuing this command you can store your Sendgrid credentials in this file

 sendgrid:
   user_name: apikey
   password: Your API key
Enter fullscreen mode Exit fullscreen mode

Under config/environment/production.rb file add in the following code

 ActionMailer::Base.smtp_settings = {
      :address => 'smtp.sendgrid.net',
      :port => '587',
      :authentication => :plain,
      :user_name => Rails.application.credentials.dig(:user_name),
      :password => Rails.application.credentials.dig(:password),
      :domain => 'heroku.com',
      :enable_starttls_auto => true
    }
    config.action_mailer.delivery_method = :smtp
  config.action_mailer.default_url_options ={:host => 'yourherokuapp.herokuapp.com', :protocol => 'https'}
Enter fullscreen mode Exit fullscreen mode

Now update the development.rb file under config/environments folder and add the following lines

 ActionMailer::Base.smtp_settings = {
      :address => 'smtp.sendgrid.net',
      :port => '587',
      :authentication => :plain,
      :user_name => Rails.application.credentials.dig(:user_name),
      :password => Rails.application.credentials.dig(:password),
      :domain => 'heroku.com',
      :enable_starttls_auto => true
    }

    config.action_mailer.delivery_method = :smtp
    config.action_mailer.default_url_options ={:host => 'http://localhost:3000'}
Enter fullscreen mode Exit fullscreen mode

This setup configuration is both for the production and development environment.
Now it is all set up. When you sign up now SendGrid will send a verification link to the registered email of the user. The confirmation link will look something like this.
Alt Text

Sendgrid verification link

If you want to redirect the user to a specific URL after they clicked the link in the confirmation email, override the after_confirmation_path_for in your confirmations_controller:

Create a new confirmations_controller.rb in app/controllers directory:

class ConfirmationsController < Devise::ConfirmationsController
  private
  def after_confirmation_path_for(resource_name, resource)
    sign_in(resource) # In case you want to sign in the user
    your_new_after_confirmation_path
  end
end
Enter fullscreen mode Exit fullscreen mode

In config/routes.rb, add this line so that Devise will use your custom ConfirmationsController. This assumes Devise operates on the users table (you may edit to match yours).

devise_for :users, controllers: { confirmations: 'confirmations' }
Enter fullscreen mode Exit fullscreen mode

Restart the webserver, and you should have it.

Top comments (3)

Collapse
 
piclez profile image
Peter WD

Quick adjustment, you need to call Rails.application.credentials.dig(:sendgrid, :user_name) to get it right. Also don't forget to pass --environment=development or other when editing your credentials.

Collapse
 
jetsondavis profile image
Jeff Davidson

Hello,

I am trying to use SendMail's dynamic templating with Devise instead of using the Devise view. Does anyone know how to override the use of the Devise email with a call to SendMail's Ruby API?

Thanks!

Collapse
 
johnedelmapa profile image
Johnedel S. Mapa

Whats the difference between apikey and yourapi key in the username and password section ?