<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicolás Proto</title>
    <description>The latest articles on DEV Community by Nicolás Proto (@nicoproto).</description>
    <link>https://dev.to/nicoproto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F561595%2F1ce096fa-b31a-4a5e-b6a8-501066f98535.jpeg</url>
      <title>DEV Community: Nicolás Proto</title>
      <link>https://dev.to/nicoproto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nicoproto"/>
    <language>en</language>
    <item>
      <title>Sign Up with LinkedIn on Rails</title>
      <dc:creator>Nicolás Proto</dc:creator>
      <pubDate>Sun, 07 Feb 2021 19:20:45 +0000</pubDate>
      <link>https://dev.to/nicoproto/sign-up-with-linkedin-on-rails-8ii</link>
      <guid>https://dev.to/nicoproto/sign-up-with-linkedin-on-rails-8ii</guid>
      <description>&lt;h3&gt;
  
  
  A simple tutorial of how to allow users to sign up to your Rails app through LinkedIn by using OAuth2.
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;After a lot of tutorials that broke in the middle of the process, stackoverflowing (I guess this works if Googling is a word now) weird bugs, and 16 cups of coffee I decided to write this tutorial with the hope to make someone’s work easier.&lt;/p&gt;

&lt;p&gt;I will be using the ruby gem &lt;a href="https://github.com/decioferreira/omniauth-linkedin-oauth2"&gt;OmniAuth LinkedIn OAuth2&lt;/a&gt; in a &lt;strong&gt;Ruby on Rails&lt;/strong&gt; application with &lt;a href="https://github.com/heartcombo/devise"&gt;Devise&lt;/a&gt; authentication.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: My actual setup is&lt;/em&gt; &lt;strong&gt;Rails&lt;/strong&gt; &lt;em&gt;6.0.3.4 and&lt;/em&gt; &lt;strong&gt;Ruby&lt;/strong&gt; &lt;em&gt;2.6.5&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  LinkedIn Setup
&lt;/h2&gt;

&lt;p&gt;First of all, to log in with LinkedIn we first need a LinkedIn app, to get one, follow these steps:&lt;/p&gt;

&lt;p&gt;1- Go to &lt;a href="https://www.linkedin.com/developers"&gt;LinkedIn Developers&lt;/a&gt;, sign in, and click on “&lt;strong&gt;Create app&lt;/strong&gt;”&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: This app needs to be associated with a company page, if you don’t have one, create it &lt;a href="https://business.linkedin.com/es-es/marketing-solutions/linkedin-pages"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;2- Fill up the form and follow the steps to &lt;strong&gt;verify&lt;/strong&gt; the app. You should get to this step where they ask you to send a &lt;strong&gt;Verification URL&lt;/strong&gt; to the Page Admin you are creating the app to 👇🏻&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wjoej5D6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A5GKCnBzD12TuASB4s1EsQQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wjoej5D6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A5GKCnBzD12TuASB4s1EsQQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The verification process should not take more than a few minutes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3- Now that you have a verified App, under the &lt;strong&gt;Products&lt;/strong&gt; tab, select “&lt;strong&gt;Sign In with LinkedIn”.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HgCLH1vy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A5_P6yHpQiVk8G_RVTh5wXw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HgCLH1vy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/1%2A5_P6yHpQiVk8G_RVTh5wXw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4- You’ll see a &lt;strong&gt;“Review in progress”&lt;/strong&gt; message, refresh your page after a few minutes until the message disappears.&lt;/p&gt;

&lt;p&gt;5- Go to the &lt;strong&gt;“Auth”&lt;/strong&gt; tab to get your &lt;strong&gt;Authentication keys (both Client ID and Client Secret)&lt;/strong&gt;, we will use them later.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LPpp9VJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3032/1%2ApCHvZNjW8dCU2SekAM-Vgg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LPpp9VJO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/3032/1%2ApCHvZNjW8dCU2SekAM-Vgg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6- Last but not least, we need to tell our LinkedIn application the &lt;strong&gt;URL&lt;/strong&gt; to &lt;strong&gt;redirect the user&lt;/strong&gt; after they successfully logged with &lt;strong&gt;LinkedIn.&lt;/strong&gt; So let’s update the &lt;strong&gt;Authorized redirect URLs for our app&lt;/strong&gt; to our development URL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rs3XMnfs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2892/0%2ALUWMh3qGEes5Jlc5" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rs3XMnfs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2892/0%2ALUWMh3qGEes5Jlc5" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rails Setup
&lt;/h2&gt;

&lt;p&gt;Because we want to focus on adding &lt;a href="https://github.com/decioferreira/omniauth-linkedin-oauth2"&gt;OAuth2&lt;/a&gt; to our application (and there are a billion tutorials on how to create a Rails app with Devise out there), we’ll begin with a basic Rails template that already has the &lt;strong&gt;Devise&lt;/strong&gt; setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails new --database postgresql -m
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: If you want, you can create your own app from scratch and follow the setup for Devise &lt;a href="https://github.com/heartcombo/devise"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rails Configuration
&lt;/h2&gt;

&lt;p&gt;Let’s start by adding our &lt;strong&gt;Authentication keys&lt;/strong&gt; using &lt;a href="https://medium.com/cedarcode/rails-5-2-credentials-9b3324851336"&gt;Rails Credential&lt;/a&gt; built-in feature (I’m using Visual Code).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;EDITOR='code --wait' rails credentials:edit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You need to add your keys this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;linkedin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;api_id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;86***********af&lt;/span&gt;
   &lt;span class="na"&gt;api_key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ns***********LQ&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: Remember this is a Yaml file, so you need to respect the indentation, the&lt;/em&gt; &lt;strong&gt;api_id&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;api_key&lt;/strong&gt; &lt;em&gt;are indented&lt;/em&gt; &lt;strong&gt;one&lt;/strong&gt; &lt;strong&gt;tab&lt;/strong&gt; &lt;em&gt;to the right.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Second, we will add the &lt;a href="https://github.com/decioferreira/omniauth-linkedin-oauth2"&gt;OmniAuth&lt;/a&gt; gem into our &lt;strong&gt;Gemfile&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"omniauth"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 1.9.1"&lt;/span&gt;
&lt;span class="n"&gt;gem&lt;/span&gt; &lt;span class="s2"&gt;"omniauth-linkedin-oauth2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and bundle it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: We are using this version of OmniAuth because the newer version is not compatible with Devise yet. &lt;a href="https://github.com/heartcombo/devise/pull/5327"&gt;See more&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now, we need to tell &lt;strong&gt;Devise&lt;/strong&gt; that we are going to use &lt;strong&gt;OmniAuth&lt;/strong&gt; with LinkedIn and where to find our &lt;strong&gt;Authentication keys.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So go to your ‘config/initializers/devise.rb’ file and &lt;strong&gt;add&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;omniauth&lt;/span&gt; &lt;span class="ss"&gt;:linkedin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:linkedin&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:api_id&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;Rails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:linkedin&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="ss"&gt;:api_key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After that, let’s allow our &lt;strong&gt;User&lt;/strong&gt; model (created by &lt;strong&gt;Devise&lt;/strong&gt;) to log in through &lt;strong&gt;OmniAuth&lt;/strong&gt;, and set the provider as &lt;strong&gt;LinkedIn&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; 
    &lt;span class="n"&gt;devise&lt;/span&gt; &lt;span class="ss"&gt;:omniauthable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;omniauth_providers: &lt;/span&gt;&lt;span class="sx"&gt;%i[linkedin]&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: You need to add that line, don’t replace the previous devise options.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Remember the &lt;strong&gt;URL&lt;/strong&gt; we told our &lt;strong&gt;LinkedIn&lt;/strong&gt; &lt;strong&gt;app&lt;/strong&gt; to go after we successfully login through LinkedIn? Let’s prepare our application to handle that route.&lt;/p&gt;

&lt;p&gt;Let’s go to our ‘config/routes.rb’ file and add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;devise_for&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;controllers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;omniauth_callbacks: &lt;/span&gt;&lt;span class="s1"&gt;'users/omniauth_callbacks'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note: The ‘devise_for :users’ should already be there, add the **controllers&lt;/em&gt;* part only.*&lt;/p&gt;

&lt;p&gt;This will create the next route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Prefix: user_linkedin_omniauth_callback 
Verb: GET|POST 
URI Pattern: /users/auth/linkedin/callback(.:format)                                                  Controller#Action: users/omniauth_callbacks#linkedin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By default, our &lt;strong&gt;User&lt;/strong&gt; created by &lt;strong&gt;Devise&lt;/strong&gt; only has the attributes &lt;strong&gt;email&lt;/strong&gt; and &lt;strong&gt;password.&lt;/strong&gt; That’s not enough if we want to take advantage of the information provided by &lt;strong&gt;LinkedIn&lt;/strong&gt;, so let’s add some attributes to our users with a migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails g migration AddProviderToUsers provider uid first_name last_name picture_url
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create the following migration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AddProviderToUsers&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Migration&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;6.0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;change&lt;/span&gt;
    &lt;span class="n"&gt;add_column&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:provider&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
    &lt;span class="n"&gt;add_column&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:uid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
    &lt;span class="n"&gt;add_column&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
    &lt;span class="n"&gt;add_column&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
    &lt;span class="n"&gt;add_column&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:picture_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:string&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run the migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails db:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So our user model has all the attributes needed, let’s add two methods in our &lt;strong&gt;User&lt;/strong&gt; model (‘app/models/user.rb’) to manage the data provided by LinkedIn:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: The&lt;/em&gt; &lt;strong&gt;first method&lt;/strong&gt; &lt;em&gt;is redefining Device&lt;/em&gt; ‘&lt;strong&gt;new_with_session&lt;/strong&gt;’ &lt;em&gt;method for our User model and the&lt;/em&gt; &lt;strong&gt;second method&lt;/strong&gt; &lt;em&gt;tries to find an existing user logged in with LinkedIn credentials (a combination of&lt;/em&gt; &lt;strong&gt;uid&lt;/strong&gt; &lt;em&gt;and&lt;/em&gt; &lt;strong&gt;provider&lt;/strong&gt;) &lt;em&gt;and if it doesn’t find one, it will create a new user with the information provided by LinkedIn.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Ok, so our User model is ready now, the next step is to create the controller that will handle the callback route we created in our app.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir app/controllers/users
touch app/controllers/users/omniauth_callbacks_controller.rb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let’s add the method that will be called when redirecting from LinkedIn.&lt;/p&gt;

&lt;p&gt;Almost done, now it’s time to test it! Let’s add a simple Bootstrap navbar to see it in action:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch app/views/shared/_navbar.html.erb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add this in your ‘_navbar.html.erb’:&lt;/p&gt;

&lt;p&gt;Don’t forget to add the &lt;strong&gt;navbar&lt;/strong&gt; and &lt;a href="https://www.bootstrapcdn.com/"&gt;Bootstrap CDN&lt;/a&gt; in your ‘application.html.erb’ file:&lt;/p&gt;

&lt;p&gt;And that’s it! Now you can try to log in by clicking on the navbar ‘login’ link and then selecting the option ‘Sign in with LinkedIn’.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q5ThDprz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AAEfIxQRAPv7epfUU.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q5ThDprz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AAEfIxQRAPv7epfUU.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aywvYp14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ARmXuscVg7DT1teeR.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aywvYp14--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2ARmXuscVg7DT1teeR.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Optional:&lt;/strong&gt; &lt;strong&gt;Edit LinkedIn user’s profile without a password&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Just in case you didn’t notice yet, Users created through this process can’t edit their profile. &lt;strong&gt;Why?&lt;/strong&gt; Because they don’t have a &lt;strong&gt;confirmation&lt;/strong&gt; password. In case you need your users to update their first_name or last_name, let’s fix that.&lt;/p&gt;

&lt;p&gt;To accomplish this, we will need to get our hands dirty into the depths of Devise Controllers and Views.&lt;/p&gt;

&lt;p&gt;First, let’s add the fields &lt;strong&gt;first_name&lt;/strong&gt; and &lt;strong&gt;last_name&lt;/strong&gt; in our ‘app/views/devise/registrations/edit.html.erb’ file so we can see them on our edit profile page:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: We also added an&lt;/em&gt; &lt;strong&gt;if&lt;/strong&gt; &lt;em&gt;statement to check if the current_user has a provider, if so, we don’t show the password fields.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now we are going to rewrite &lt;strong&gt;Devise’s Registration Controller&lt;/strong&gt;, so first we are going to generate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rails generate devise:controllers "" -c=registrations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we’ll tell our Devise routes to use this new controller by updating our ‘route.rb’ file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;devise_for&lt;/span&gt; &lt;span class="ss"&gt;:users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;controllers: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;omniauth_callbacks: &lt;/span&gt;&lt;span class="s1"&gt;'users/omniauth_callbacks'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;registrations: &lt;/span&gt;&lt;span class="s1"&gt;'registrations'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And let’s replace the content of that ‘registrations_controller.rb’ so it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Long story short, we are telling&lt;/em&gt; &lt;strong&gt;Devise&lt;/strong&gt; &lt;em&gt;that if the&lt;/em&gt; &lt;strong&gt;User&lt;/strong&gt; &lt;em&gt;that’s trying to update their profile has logged through&lt;/em&gt; &lt;strong&gt;LinkedIn&lt;/strong&gt; &lt;em&gt;(their&lt;/em&gt; &lt;strong&gt;provider&lt;/strong&gt; &lt;em&gt;attribute is&lt;/em&gt; &lt;strong&gt;not&lt;/strong&gt; &lt;strong&gt;blank&lt;/strong&gt;) &lt;em&gt;we should update without requesting the password.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Finally&lt;/strong&gt;, we need to allow the new attributes to go through the &lt;strong&gt;devise_parameter_sanitizer&lt;/strong&gt; (security reasons) and we can do that by adding this to our ‘application_controller.rb’ file:&lt;/p&gt;

&lt;p&gt;And that’s it! You are now able to update your first_name and last_name fields even if you signed up through LinkedIn.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wOJpXaur--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AOQBghqW_ceEuhF8l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wOJpXaur--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2AOQBghqW_ceEuhF8l.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What about production?
&lt;/h2&gt;

&lt;p&gt;In production, we just need to configure our Rails Credentials Master Key in the hosting provider we use. For example, if you are using &lt;a href="https://www.heroku.com/"&gt;Heroku&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;heroku config:set RAILS_MASTER_KEY=30**************************354d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, we should update our callback &lt;strong&gt;URL&lt;/strong&gt; from the &lt;strong&gt;LinkedIn app&lt;/strong&gt; to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pqffN0YQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2As_HY97GTWKmSTO0T" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pqffN0YQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/2000/0%2As_HY97GTWKmSTO0T" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you wonder who wrote this, let me speak about myself.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;My name is Nico Proto and I’m a developer at my web development agency &lt;a href="http://www.mangotree.dev/"&gt;MangoTree&lt;/a&gt;. If you are curious about what we do (you should) connect with me through &lt;a href="https://www.linkedin.com/in/nicolas-proto/"&gt;Linkedin&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
