<?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>Forem: Antonieta Alvarez</title>
    <description>The latest articles on Forem by Antonieta Alvarez (@antoalconti).</description>
    <link>https://forem.com/antoalconti</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%2F476827%2Ff2d31460-548e-45d0-80cd-e512430d052c.JPG</url>
      <title>Forem: Antonieta Alvarez</title>
      <link>https://forem.com/antoalconti</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/antoalconti"/>
    <language>en</language>
    <item>
      <title>AppleAuth: Ruby Gem for Apple Sign in Rails Integration</title>
      <dc:creator>Antonieta Alvarez</dc:creator>
      <pubDate>Fri, 10 Jun 2022 15:37:36 +0000</pubDate>
      <link>https://forem.com/rootstrap/appleauth-ruby-gem-for-apple-sign-in-rails-integration-3cl3</link>
      <guid>https://forem.com/rootstrap/appleauth-ruby-gem-for-apple-sign-in-rails-integration-3cl3</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h5c59oWo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93ryggfryr3v7c3v2wwn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h5c59oWo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/93ryggfryr3v7c3v2wwn.png" alt="Person walking in front of an apple store" width="880" height="1110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AppleAuth?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://rubygems.org/gems/apple_auth"&gt;AppleAuth&lt;/a&gt; is a Ruby gem we developed to integrate Apple Sign In in our server side applications.&lt;/p&gt;

&lt;p&gt;Apple announced Sign in with Apple in the &lt;a href="https://developer.apple.com/videos/play/wwdc2019/706/"&gt;WWDC 2019 Conference&lt;/a&gt;, then in September 2019 Apple updated its &lt;a href="https://developer.apple.com/news/?id=09122019b"&gt;App Store Review Guideline&lt;/a&gt; to state that if your iOS app implements a third-party or social login service (like Facebook Login or Google Sign-In) it will be mandatory to offer Apple sign in as an option by the end of April 2020.  Besides following the standards, implementing apple authentication will let sign in using their two-factor authentication Apple ID. After the user follows Sign in with Apple to log in, your app receives tokens and user information that you can use to authenticate the user in your server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apple sign-in workflow
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5p9bvSQv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1w2frzn34chtuo6fs68.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5p9bvSQv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o1w2frzn34chtuo6fs68.png" alt="Apple sign in flow" width="880" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For more information, check the &lt;a href="https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api"&gt;Apple Official Documentation&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How does AppleAuth works?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Validation
&lt;/h3&gt;

&lt;p&gt;Apple authentication follows the OAuth 2.0 flow, and this gem will help us with this flow. After the user signs in the client-side, we will have access to the user_identity, code, and JWT on our server-side. The last one is a token that will be used to validate user authentication with Apple. So Apple_Auth's first step will be to decode and validate the JWT.&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="c1"&gt;# with a valid JWT&lt;/span&gt;
&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'000343.1d22d2937c7a4e56806dfb802b06c430...'&lt;/span&gt;
&lt;span class="n"&gt;valid_jwt_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'eyJraWQiOiI4NkQ4OEtmIiwiYWxnIjoiUlMyNTYifQ.eyJpc...'&lt;/span&gt;
&lt;span class="no"&gt;AppleAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UserIdentity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;valid_jwt_token&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;validate!&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;exp: &lt;/span&gt;&lt;span class="mi"&gt;1595279622&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email: &lt;/span&gt;&lt;span class="s2"&gt;"user@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;email_verified: &lt;/span&gt;&lt;span class="kp"&gt;true&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="c1"&gt;# with an invalid JWT&lt;/span&gt;
&lt;span class="n"&gt;invalid_jwt_token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'eyJraWQiOiI4NkQsd4OEtmIiwiYWxnIjoiUlMyNTYifQ.edsyJpc...'&lt;/span&gt;
&lt;span class="no"&gt;AppleAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;UserIdentity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;invalid_jwt_token&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;validate!&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;  &lt;span class="no"&gt;AppleAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Conditions&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;JWTValidationError&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

&lt;p&gt;If we successfully validate the JWT, we can authenticate users and get their information. At this point, we can persist refresh-token, to once a day, and if needed get a fresh token from Apple and ensure that the user continues to have their apple_id validated.&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;code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'cfb77c21ecd444390a2c214cd33decdfb.0.mr...'&lt;/span&gt;
&lt;span class="no"&gt;AppleAuth&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Token&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;authenticate!&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;access_token: &lt;/span&gt;&lt;span class="s2"&gt;"a7058d..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;expires_at: &lt;/span&gt;&lt;span class="mi"&gt;1595894672&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;refresh_token: &lt;/span&gt;&lt;span class="s2"&gt;"r8f1ce..."&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DeviseTokenAuth Integration
&lt;/h3&gt;

&lt;p&gt;If you already have DeviseTokenAuth gem implemented on your Rails project, you can just run this generator:&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 apple_sign_in:appple_auth_controller [scope]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the scope you need to write your path from controllers to your existent devise controllers and set up the routes.&lt;/p&gt;

&lt;p&gt;This generator will create a controller, that implements AppleAuth methods, get the user's email, and register them.&lt;/p&gt;

&lt;p&gt;You can find more info and the guide to install the gem on the &lt;a href="https://github.com/rootstrap/apple_auth"&gt;README&lt;/a&gt;.&lt;br&gt;
You can find a full implementation of this gem in this &lt;a href="https://github.com/rootstrap/apple-sign-in-rails"&gt;demo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Read this article and more content in the Rootstrap blog: &lt;a href="https://www.rootstrap.com/blog"&gt;https://www.rootstrap.com/blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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