Whilst scrolling through the world wide web, have you ever encountered buttons with titles such as “Sign in with ‘X' service”? Well, those are there for a reason, and their purpose is to make your, and the developer’s life easier. Much easier. Let me explain why.
Back in the early days of web development, for a user to sign in and create a user session, they had to authorize themselves via their credentials - mainly their email and password. All users, and their corresponding credentials, were stored on a backend server and used to compare form-given credentials to authorize the user and grant them a session. That way, a user was authorized and could proceed to access the website. However, due to safety reasons and maintenance issues, using this kind of user authorization scheme has been proven to be bad practice nowadays.
One big concern during those times had been exposing user credentials to external services. Before the appearance of OAuth, in order to use an external service, a user had to provide their credentials to that service, which in turn would allow the service to perform certain actions on the user’s behalf.
Think of it this way - you’re a user, and the year is 2007. You’ve signed up to a new website, but now that website wants you to share your thoughts and experiences with people outside that website’s domain. In this case, it wants to use an external service like Gmail. The website asks for your Gmail address and password so it can log into your account and send emails to all of your contacts. Afterward, the website promises to forget your password and never use it again. Would you trust such a claim?
Yeah, neither would I. OAuth was developed to avoid such security risks. Generally, all OAuth does is redirect you to the domain of the external service upon which you are asked to authorize yourself. In short, instead of allowing a random website to obtain your user information for an external service, you are authorizing yourself via that external service using their domain. Short, simple, and safe, just how we like it. On another note, as proof of successful user authorization, OAuth provides you with an access token allowing access to the website’s API service.
How to Easily Set up an External Authorization Procedure
This blog post is going to demonstrate how you can implement the “Sign in Microsoft” button with its full functionality by using Ruby 3.0.0 and Rails 7.0.2. Setting up an external Microsoft authorization prompt uses the same OAuth approach as explained above. In this case, OmniAuth is the gem that will be used for multi-provider OAuth authentication. We have to use the Microsoft Office OmniAuth strategy (gem) to implement it. The following is everything needed for the task:
Adding the CSRF protection gem is necessary for being able to mitigate issues with Cross-Site Request Forgery on the request phase when using the OmniAuth gem with a Rails application.
The next important step is registering a new Microsoft application from which we can get a Client ID and Client Secret. That can be done in the Microsoft Azure portal.
Before returning to the application side, make sure to set the homepage URL and callback URL on the Azure portal side. The homepage URL is the default server that is used when you run rails server, which in this case is: http://localhost:3000. The callback URL is where the office strategy is directed after the authentication process, whether or not the user passes the authentication. In our case, it will be set to: http://localhost:3000/auth/microsoft_office365/callback
The Client ID (Application ID), and the Client Secret (Application Secret) are used to validate and recognize requests that are coming from your application. They’re linked to the application side and, as such, will be saved as environment variables (this is why the 'dotenv-rails' is being used):
Once the authorization server has been set up, our application will accept requests and redirect towards the Microsoft OAuth strategy. For user authentication on the application’s side, we use Devise, whose setup is well explained on the official Github page.
First, an update on how the error messages are being handled is required:
Afterward, the following have to be added to the devise initializer.
Now, Devise has been properly initialized to work with Turbo and Rails 7 fully. The authorization application has also been set up with the proper callback URL. The only thing left to do is add the button and the logic behind it and apply it to a real-world example.
Since we’re doing user authentication and authorization, we need users to begin with. Devise offers a great tool for generating everything we need for that: rails g devise user. Now, after that, we'll need two columns added to your users table so that a user can hold an 'uid' and a 'provider'. These we'll be populated once the office OmniAuth strategy has successfully authenticated a user.
To do so, make migration with: rails g migration add_oauth_support_to_users and add the following lines:
Run rails db:migrate.
In the User model, update the devise part of the code to look like this:
In the same file, we'll add a new method to deal with the callback data that the strategy will provide:
For the last step, we need to create a route for this. Since we’re doing with Devise, the routes have already been implemented, but we need to intercept them to add the OmniAuth part of the logic. In the ‘routes.rb’ file, make sure to add the following:
For Devise to understand additional logic happening during the authentication process, we need to add our own controller, which looks like the following:
This flow creates a new user and saves the information in an instance variable ‘@user’. Next, if the user persisted in the external validation process, they’re signed in, and if not, they’re redirected to the registration page. That should be it, you should be ready to use your own “Sign in with Office365” button. 🙂
If OmniAuth decides not to cooperate with your project when dealing with raised exceptions after unsuccessful login attempts, try adding the following initializer, and it may aid the setting up process:
Wrap Up: How to Create a Fully Working “Sign in With Microsoft” Authorization Button
In order to be able to implement your own “Sign in with Microsoft” authorization button, you would need to do the following:
Include the OmniAuth gem in your project (along with the OmniAuth Office strategy, and other dependencies explained at the beginning of this post)
Setup your application via the Microsoft Azure portal
Retrieve your Application Key & Application Secret from the Azure portal, and save them on the Application side (preferably using a .env file)
Add required error message handling updates
Add required Devise initializer changes
Add database changes, configure callback methods, edit routes, add a custom controller for handling authorizations
There you go! A fully working "Sign in with Microsoft" authorization button that functions the same way as the ones you've seen everywhere online!
Now that you know this, you may have no issues implementing other OmniAuth strategies on your own. The premise stays the same:
Find the OmniAuth strategy you want to implement
Create a server side application using the strategy provider (i.e. Google, Facebook, Reddit, etc.)
Implement the authorization part on the application side
You're finished - it's as simple as that!
I’d personally advise trying to implement the Google authorization strategy next as it seems to be the simplest one to do. Give it a go, and I hope you make it through the challenge.
Devōt Listed on Clutch’s Top 100 Fastest Growing Companies for 2022!
As a growing software development company, there is no better review site to be featured on than Clutch. It is an established ratings and reviews platform for B2B service providers, including companies from over 100 countries and 500 industries. We’re beyond excited to announce that Devōt was showcased as a Top 100 fastest-growing company in 2022 by Clutch.Read
How to Install Unsupported Development Software on M1 Macs
From the new release in November 2020, Apple released the first Mac with an ARM-based M1 chip. The M1 chip marks Apple's transition from Intel chips that have been used for the last 15 years. If you are worried about transitioning your existing project from your Intel-based Mac, this blog could make your transition easier.Read