<?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: Mert Yerekapan</title>
    <description>The latest articles on Forem by Mert Yerekapan (@mertyerekapan).</description>
    <link>https://forem.com/mertyerekapan</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%2F852985%2F55c117d8-4cab-4bda-b0cf-41f8767ecfad.jpg</url>
      <title>Forem: Mert Yerekapan</title>
      <link>https://forem.com/mertyerekapan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mertyerekapan"/>
    <language>en</language>
    <item>
      <title>How to implement Two-Factor Authentication using Next.js, Twilio and Altogic</title>
      <dc:creator>Mert Yerekapan</dc:creator>
      <pubDate>Fri, 13 May 2022 12:43:23 +0000</pubDate>
      <link>https://forem.com/altogic/how-to-implement-two-factor-authentication-using-nextjs-twilio-and-altogic-ok0</link>
      <guid>https://forem.com/altogic/how-to-implement-two-factor-authentication-using-nextjs-twilio-and-altogic-ok0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article will cover &lt;strong&gt;two-factor authentication&lt;/strong&gt; basics using &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;, &lt;a href="https://twilio.com/" rel="noopener noreferrer"&gt;Twilio&lt;/a&gt;, and &lt;a href="https://altogic.com/" rel="noopener noreferrer"&gt;Altogic&lt;/a&gt;, a Backend-as-a-Service platform using its client library. This authentication method allows users to add one more security layer to their application. Many people enable their &lt;strong&gt;two-factor authentication&lt;/strong&gt; settings to increase their security using their phone numbers or authentication apps for security purposes.&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-two-factor-authentication" rel="noopener noreferrer"&gt;source code&lt;/a&gt; and &lt;a href="https://altogic-nextjs-two-factor-auth.vercel.app/" rel="noopener noreferrer"&gt;demo app&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How is the two-factor authentication flow?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Users who already have an account need to set their phone number to enable two-factor authentication.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An SMS with a code is sent to the specified phone number by &lt;strong&gt;Altogic and Twilio&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users verify their phone number by entering the code sent to their phone number.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users can enable or disable the two-factor authentication setting from their profile.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When users try to sign in, if two-factor authentication is enabled, a code is sent to the specified phone number by &lt;strong&gt;Altogic and Twilio.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users verify their identity by entering the code on the input on the screen.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If two-factor authentication is not enabled, they can sign in without this process.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Youtube Showcase Video
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/iZHgR1_W8vk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the Project
&lt;/h2&gt;

&lt;p&gt;This project builds on top of the complete e-mail authentication app we created previously. You can follow the &lt;a href="https://medium.com/altogic/altogic-email-authentication-with-next-js-and-altogic-4c036c36ea8f" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; to build the same app or clone the project from &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-email-authentication" rel="noopener noreferrer"&gt;here&lt;/a&gt; and continue with the rest of the tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Twilio Integration
&lt;/h2&gt;

&lt;p&gt;You need to sign up for &lt;strong&gt;Twilio&lt;/strong&gt; with a free/paid trial. You need to get the &lt;strong&gt;Account SID&lt;/strong&gt; and &lt;strong&gt;Auth Token&lt;/strong&gt; for integration with Altogic Client Library.&lt;/p&gt;

&lt;p&gt;If you use the free trial, you will need to take the &lt;strong&gt;Twilio&lt;/strong&gt; phone number to send SMS messages to the users.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create an Account on &lt;em&gt;Twilio&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;strong&gt;Console&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click “Get a trial phone number” on the left-top of the Console&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy &lt;strong&gt;Account SID&lt;/strong&gt;, &lt;strong&gt;Auth Token,&lt;/strong&gt; and &lt;strong&gt;My Twilio phone number&lt;/strong&gt; values to the clipboard&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AFjkgv5P9FCTkF62u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2800%2F0%2AFjkgv5P9FCTkF62u.png" alt="Twilio Credentials"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we’ve copied the configuration credentials to the clipboard. You must specify the verified phone numbers in trial accounts, which we defined as “ &lt;em&gt;to number”&lt;/em&gt; in &lt;strong&gt;Altogic&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Click on the &lt;strong&gt;Explore Products&lt;/strong&gt; in the left sidebar.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Be sure that &lt;strong&gt;Messaging&lt;/strong&gt; and &lt;strong&gt;Phone Numbers&lt;/strong&gt; products are selected.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now you can navigate to the &lt;strong&gt;Verified Caller IDs&lt;/strong&gt; page by &lt;strong&gt;Sidebar → Phone Numbers → Manage → Verified Caller IDs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AuyjZHk6tFYytA34Y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2AuyjZHk6tFYytA34Y.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should add your phone number as a Verified Caller from here.&lt;/p&gt;

&lt;p&gt;And finally, you have to give geo permission to your phone numbers region. You can go to this page by &lt;strong&gt;Sidebar&lt;/strong&gt; → &lt;strong&gt;Messaging&lt;/strong&gt; → &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Geo permissions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A-PLQ3y-NeudqR2hg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2000%2F0%2A-PLQ3y-NeudqR2hg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the models
&lt;/h2&gt;

&lt;p&gt;Models define the &lt;strong&gt;data structure and data validation rules&lt;/strong&gt; of your applications. A model is composed of &lt;strong&gt;basic&lt;/strong&gt;, &lt;strong&gt;advanced,&lt;/strong&gt; and &lt;strong&gt;sub-model&lt;/strong&gt; &lt;strong&gt;fields&lt;/strong&gt;. As an analogy, you can think of models as tables and fields as columns in relational databases or models as documents and fields as document properties in non-relational databases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3590%2F0%2AjOvv0K2lUO1dk6Ro" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3590%2F0%2AjOvv0K2lUO1dk6Ro" alt="Key entities in Altogic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we create our application, &lt;strong&gt;a user model is created&lt;/strong&gt; by default. We need to add a &lt;strong&gt;boolean field&lt;/strong&gt; to this user model to let users &lt;strong&gt;enable&lt;/strong&gt; and &lt;strong&gt;disable&lt;/strong&gt; the two-factor authentication.&lt;/p&gt;

&lt;p&gt;To create a field via the Designer, you need to &lt;strong&gt;Navigate to Models&lt;/strong&gt; view and select the model you would like to add the new field. You will be directed to the model details view.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5368%2F1%2AwNMd344wRFEmdVWm-WXppg%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5368%2F1%2AwNMd344wRFEmdVWm-WXppg%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In the model details view, select &lt;strong&gt;New field.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the dropdown menu, &lt;strong&gt;select&lt;/strong&gt; the &lt;strong&gt;Boolean&lt;/strong&gt; that you would like to create.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the field name, type “&lt;strong&gt;twoFactorAuth&lt;/strong&gt;” and set a default value of false&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Create&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2392%2F1%2AvbZntcm568IFmlTnqFn00g%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2392%2F1%2AvbZntcm568IFmlTnqFn00g%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to create a new model called &lt;strong&gt;phoneVerificationCode&lt;/strong&gt; to handle the verification code we send to users’ phone numbers. This data type will be a &lt;strong&gt;Transient&lt;/strong&gt; data type meaning it is not stored in the database. We are defining it as &lt;strong&gt;Transient&lt;/strong&gt; because we don’t need it after completing the verification.&lt;/p&gt;

&lt;p&gt;To create a model via the Designer, you have two options. You can either create a model from scratch or a sample JSON document. In either case, first, you need to navigate to the &lt;strong&gt;Models view&lt;/strong&gt; in designer and select &lt;strong&gt;+New&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5364%2F1%2AsDm3NGTyXTUxQryR4Wb2fw%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5364%2F1%2AsDm3NGTyXTUxQryR4Wb2fw%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After, you can pick a &lt;strong&gt;Model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2392%2F1%2A6VQM6b2shrdweT_o80UTfQ%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2392%2F1%2A6VQM6b2shrdweT_o80UTfQ%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And create the &lt;strong&gt;phoneVerificationCode&lt;/strong&gt; model. Afterward, we need to add three fields:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;code&lt;/strong&gt; field, which is an &lt;strong&gt;Integer&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;userId&lt;/strong&gt; field, which is an &lt;strong&gt;Object reference&lt;/strong&gt; to the &lt;strong&gt;users&lt;/strong&gt; model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;phoneNumber&lt;/strong&gt; field, which is a &lt;strong&gt;Text&lt;/strong&gt; field.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5360%2F1%2AiE7PaDia0KjitAUL75EE9A%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F5360%2F1%2AiE7PaDia0KjitAUL75EE9A%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create the endpoints
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Endpoints&lt;/strong&gt; are the communication channels to access the services provided in your applications, and through endpoints, you &lt;strong&gt;expose&lt;/strong&gt; your application services and data &lt;strong&gt;to the outside world&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To create an endpoint via the Designer, you need to navigate the &lt;strong&gt;Endpoints view&lt;/strong&gt; in designer and select &lt;strong&gt;New-&amp;gt;Endpoint.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F10240%2F1%2Al4aFW2BIB7BvOVo7V35RvQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F10240%2F1%2Al4aFW2BIB7BvOVo7V35RvQ.png" alt="How to create endpoints in Altogic Designer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After clicking, you need to enter a relevant endpoint name and optionally pick a group, pick a method, specify the path and assign a service that handles the requests to the endpoint.&lt;/p&gt;

&lt;p&gt;We can also click on the “Session required” checkbox, which enforces a need for a session when a request is made to the endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2384%2F1%2A29q_MAhK1YNGR8lz8XmawQ%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2384%2F1%2A29q_MAhK1YNGR8lz8XmawQ%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, our method is “&lt;strong&gt;POST&lt;/strong&gt;,” and our path is “&lt;strong&gt;/users/set-phone&lt;/strong&gt;” meaning that if we send a &lt;strong&gt;POST&lt;/strong&gt; request to this path, the service we define will run. We created a service by clicking “&lt;strong&gt;Add new service&lt;/strong&gt;” and by naming our service, we will be created an empty service. We will design the service next.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2384%2F1%2A6q82ovkRXn1WhRQetBXn-w%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2384%2F1%2A6q82ovkRXn1WhRQetBXn-w%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will create &lt;strong&gt;three more endpoints&lt;/strong&gt; to verify the code while changing the phone, signing in, and implementing the particular sign-in functionality.&lt;/p&gt;

&lt;p&gt;Create the verify code during changing phone endpoint:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2380%2F1%2A5GPJRB0kJ_ig2iFsiEIFeg%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2380%2F1%2A5GPJRB0kJ_ig2iFsiEIFeg%402x.png" alt="Verify code during changing phone endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the verify code during the sign-in endpoint:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2384%2F1%2AvCLguYn61c4uREcRAlUpfQ%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2384%2F1%2AvCLguYn61c4uREcRAlUpfQ%402x.png" alt="Verify code during sign-in endpoint"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the sign-in endpoint for implementing the particular 2-FA logic:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2392%2F1%2AebDWbWzWx2uoAMR5SKvCrg%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2392%2F1%2AebDWbWzWx2uoAMR5SKvCrg%402x.png" alt="Sign in endpoint for implementing the specific 2-FA logic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we created our endpoints and services, we can start &lt;strong&gt;designing&lt;/strong&gt; the services, which is the &lt;strong&gt;most fun part&lt;/strong&gt; of using &lt;strong&gt;Altogic&lt;/strong&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Design the Services
&lt;/h2&gt;

&lt;p&gt;Building the flow of service involves three main activities.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Adding the right node from the &lt;strong&gt;nodes library&lt;/strong&gt; to the &lt;strong&gt;service flow area.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Customizing the added node parameters using the &lt;strong&gt;node properties panel.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Linking the &lt;strong&gt;output link point&lt;/strong&gt; of a node to the &lt;strong&gt;input link point&lt;/strong&gt; of another node using relations.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;First, we will implement the &lt;strong&gt;“Set phone number service.”&lt;/strong&gt; We have the start node, which is used to start the execution of the endpoint handling service. It runs only once at the start of the service to trigger nodes connected to its output link point. We define a query string parameter of type text named “phoneNumber” as input for this endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2924%2F1%2AnkDzaz6-j9lRJT53Bc22SA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2924%2F1%2AnkDzaz6-j9lRJT53Bc22SA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we check if the phone number sent is a valid phone number with the &lt;strong&gt;ISMOBILEPHONE()&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3052%2F1%2AD-_W4oUTdXQkizH4ZWiCXg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3052%2F1%2AD-_W4oUTdXQkizH4ZWiCXg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If no, return an error response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2916%2F1%2AA1CFsOtXQZaDurzdaN8Yzg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2916%2F1%2AA1CFsOtXQZaDurzdaN8Yzg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If yes, create an object of &lt;strong&gt;phoneVerificationCode&lt;/strong&gt; model. For code, we generate a random number with &lt;strong&gt;RANDBETWEEN()&lt;/strong&gt; function and insert the other fields from either the input or the session.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3044%2F1%2ALKXs8nX-jsK_wG2y-nxuRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3044%2F1%2ALKXs8nX-jsK_wG2y-nxuRw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cache the object we created so we can access it later for verifying the code. I want the code to expire after one minute, so I set the timeout value to 1 minute.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3228%2F1%2AHR3DBjnvxS2kIVQtR6H7FA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3228%2F1%2AHR3DBjnvxS2kIVQtR6H7FA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Send the SMS message to the specified phone number with the code. Here we use the Twilio credentials we obtained.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3120%2F1%2AB3JEBKCDPgUHRyXPBUcrHQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3120%2F1%2AB3JEBKCDPgUHRyXPBUcrHQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we return the success response. This is the final look of our service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3316%2F1%2AzcPAj4TcKj0-0fs6krdOvw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3316%2F1%2AzcPAj4TcKj0-0fs6krdOvw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we will implement the &lt;strong&gt;“Verify code in change phone service.”&lt;/strong&gt; This service is used to verify the code when users want to change their phone numbers.&lt;/p&gt;

&lt;p&gt;We have the start node, which is used to start the execution of the endpoint handling service. It runs only once at the start of the service to trigger nodes connected to its output link point. We define the request body structure as a single model of “&lt;strong&gt;phoneVerificationCode&lt;/strong&gt;” as input for this endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2940%2F1%2ARNo9Q67RMaiKk1hWMY36nw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2940%2F1%2ARNo9Q67RMaiKk1hWMY36nw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get the cached object with the phone number to check the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2936%2F1%2Aa9xgDJadobGlYRWCCS5CiQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2936%2F1%2Aa9xgDJadobGlYRWCCS5CiQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return an error response if the cached object does not exist anymore. It means that the code is expired and no longer valid.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2844%2F1%2AMVUdDWSl5nQeschEDgnn7Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2844%2F1%2AMVUdDWSl5nQeschEDgnn7Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check if the cached code is &lt;strong&gt;equal&lt;/strong&gt; to the code sent in the “&lt;strong&gt;phoneVerificationCode&lt;/strong&gt;” object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2976%2F1%2AMyE-KwLMtZt0n5HT9I-DsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2976%2F1%2AMyE-KwLMtZt0n5HT9I-DsQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update the user's phone number and set the “&lt;strong&gt;phoneVerified&lt;/strong&gt;” to true using the “&lt;strong&gt;Update Object Fields by Id&lt;/strong&gt;” node. We need to set the updated object model to “&lt;strong&gt;users&lt;/strong&gt;” and object id to the userId, and we do that by giving the &lt;strong&gt;userId&lt;/strong&gt; we obtain from &lt;strong&gt;phoneVerificationCode&lt;/strong&gt; object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2932%2F1%2AW-x8CF5gbpXvPusHGMA5TA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2932%2F1%2AW-x8CF5gbpXvPusHGMA5TA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we return the success response. This is the final look of our service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2932%2F1%2Ak9o3tH28zaHaeJpKL_droA%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2932%2F1%2Ak9o3tH28zaHaeJpKL_droA%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we will implement the &lt;strong&gt;“Verify code in sign-in service.”&lt;/strong&gt; This service is used to verify the code when users try to sign in when their two-factor authentication is enabled.&lt;/p&gt;

&lt;p&gt;We have the start node, which is used to start the execution of the endpoint handling service. It runs only once at the start of the service to trigger nodes connected to its output link point. We define the request body structure as a single model of “&lt;strong&gt;phoneVerificationCode&lt;/strong&gt;” as input for this endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2780%2F1%2Ak2FpvseVrlnmQgLil6nT2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2780%2F1%2Ak2FpvseVrlnmQgLil6nT2g.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get the cached object with the phone number to check the code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2912%2F1%2ArC2PZbcgE_9WqmJ4gCbObQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2912%2F1%2ArC2PZbcgE_9WqmJ4gCbObQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return an error response if the cached object does not exist anymore. It means that the code is expired and no longer valid.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2844%2F1%2AMVUdDWSl5nQeschEDgnn7Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2844%2F1%2AMVUdDWSl5nQeschEDgnn7Q.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check if the cached code is &lt;strong&gt;equal&lt;/strong&gt; to the code sent in the “&lt;strong&gt;phoneVerificationCode&lt;/strong&gt;” object.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2936%2F1%2AJmd6ST-imyKzq7mshzZIoA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2936%2F1%2AJmd6ST-imyKzq7mshzZIoA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return error if code is not equal to the one sent in the input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2860%2F1%2ArgvY5C6syY_Ty7ZynInoMg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2860%2F1%2ArgvY5C6syY_Ty7ZynInoMg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get the user using the “&lt;strong&gt;Get Single Object by Query&lt;/strong&gt;” node. We need to set the &lt;strong&gt;retrieved object model&lt;/strong&gt; to &lt;strong&gt;users,&lt;/strong&gt; and our query should be this.phone==inputObject.phoneNumber to get the user with the specified phone.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2912%2F1%2Asr7d0cpMHrA0R5QRARRhLw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2912%2F1%2Asr7d0cpMHrA0R5QRARRhLw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there is no user, return an error response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2708%2F1%2ADLpzhDesjEV1F6FMF8V_Fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2708%2F1%2ADLpzhDesjEV1F6FMF8V_Fw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If there is a user, create a user session.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2864%2F1%2A1MUgIL6ewWHScyPljyKDEg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2864%2F1%2A1MUgIL6ewWHScyPljyKDEg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we return the success response. This is the final look of our service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3372%2F1%2AnX5kVhHiQ5sKap6py5R32g%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3372%2F1%2AnX5kVhHiQ5sKap6py5R32g%402x.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, we will implement the &lt;strong&gt;“Sign in service.”&lt;/strong&gt; This service is used to implement the sign-in feature. Because we want to use two-factor authentication, we can’t use the function in the client library, and we have to design it ourselves. But don’t worry, designing complex business logic in &lt;strong&gt;Altogic&lt;/strong&gt; is relatively easy! :)&lt;/p&gt;

&lt;p&gt;We have the start node, which is used to start the execution of the endpoint handling service. It runs only once at the start of the service to trigger nodes connected to its output link point. We define a query string parameter of type email named “&lt;strong&gt;email&lt;/strong&gt;” and type text called “&lt;strong&gt;password&lt;/strong&gt;” as input for this endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3024%2F1%2AgEt0rT29AtvAVAWMcvRRug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3024%2F1%2AgEt0rT29AtvAVAWMcvRRug.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Get the user using the “&lt;strong&gt;Get Single Object by Query&lt;/strong&gt;” node. We need to set the &lt;strong&gt;retrieved object model&lt;/strong&gt; to &lt;strong&gt;users,&lt;/strong&gt; and our query should be this.email==params.body.email to get the user with the specified email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2856%2F1%2AvXyzYdQd-IXo9RNPrRavBQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2856%2F1%2AvXyzYdQd-IXo9RNPrRavBQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return an error if there is no user with the specified email.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2640%2F1%2AsmuLN2HkfsNLmtQnunwdBw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2640%2F1%2AsmuLN2HkfsNLmtQnunwdBw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use the &lt;strong&gt;“If-Else Condition&lt;/strong&gt;” node to check if the emailVerified field of the user is true or not.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2804%2F1%2ApJis4ccGRiuOmE4eoIuLiQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2804%2F1%2ApJis4ccGRiuOmE4eoIuLiQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the email is not verified, return an error response.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2816%2F1%2AkkDs3gEcOUf3s819Mft_gA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2816%2F1%2AkkDs3gEcOUf3s819Mft_gA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compare the password sent with the password in the database with &lt;strong&gt;ECOMPARE()&lt;/strong&gt; function. This function compares the password text in the input with the password in the database but &lt;strong&gt;does not expose&lt;/strong&gt; the encrypted password. No one, including the developer, can see the user's passwords.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2836%2F1%2AV5SaHpMIjVkA5MncU74Mqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2836%2F1%2AV5SaHpMIjVkA5MncU74Mqw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Return an error response if passwords do not match.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2744%2F1%2AGwqEcn7G3izZMxJRUry-Fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2744%2F1%2AGwqEcn7G3izZMxJRUry-Fw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check if the &lt;strong&gt;two-factor authentication&lt;/strong&gt; of the user is enabled.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2648%2F1%2A-K5POX5meS0vgJYMCG7ZGg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2648%2F1%2A-K5POX5meS0vgJYMCG7ZGg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If two-factor authentication of the user is not enabled, create the user session and return it with the user data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2852%2F1%2AHN4mcUgqwbM3N-MgugRmwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2852%2F1%2AHN4mcUgqwbM3N-MgugRmwg.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If enabled, create an object of &lt;strong&gt;phoneVerificationCode&lt;/strong&gt; model. For code, we generate a random number with &lt;strong&gt;RANDBETWEEN()&lt;/strong&gt; function and insert the other fields from the input.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3284%2F1%2AEZAwI3iGsquthZ8syGCwcw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3284%2F1%2AEZAwI3iGsquthZ8syGCwcw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cache the object we created so we can access it later for verifying the code. I want the code to expire after one minute, so I set the timeout value to 1 minute.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2996%2F1%2AKCckXGETVD4z3I-Fzg6W4w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2996%2F1%2AKCckXGETVD4z3I-Fzg6W4w.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Send the SMS message to the specified phone number with the code. Here we use the Twilio credentials we obtained.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2924%2F1%2AhG0LEpSjCwtYbrcUFm4MOQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2924%2F1%2AhG0LEpSjCwtYbrcUFm4MOQ.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then we return the success response. This is the final look of our service:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4916%2F1%2A_FPVaXTVi8QhUZoGVuNqTA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F4916%2F1%2A_FPVaXTVi8QhUZoGVuNqTA.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To learn more about building the service flows, check out the &lt;a href="https://docs.altogic.com/help-guides/building-services/service-flow" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Start Coding!
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Set/Change phone functionality
&lt;/h3&gt;

&lt;p&gt;To enable two-factor authentication, users need to set up their phone numbers. This functionality is the same as &lt;strong&gt;changing the phone functionality&lt;/strong&gt; so that we will use the same screen with some minor conditional UI changes.&lt;/p&gt;

&lt;p&gt;We have already created the endpoint and designed the service. We need to send a request to the endpoint using &lt;strong&gt;Altogic Client Library&lt;/strong&gt; using &lt;strong&gt;EndpointManager&lt;/strong&gt; and the post method like &lt;strong&gt;altogic.endpoint.post()&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  SMS verify during change phone functionality
&lt;/h3&gt;

&lt;p&gt;Code above runs the service for setting/changing the phone number and sending the SMS for verification code. Now, users need a screen to enter the SMS code. We have already created the endpoint and designed the service for this case. We need to send a request to that particular endpoint.&lt;/p&gt;

&lt;p&gt;Here is the code for that:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Toggle Two Factor Authentication functionality
&lt;/h3&gt;

&lt;p&gt;Users should be able to switch on and off two-factor authentication if they want to. For this, we are implementing a basic switch. We are updating the &lt;strong&gt;twoFactorAuth&lt;/strong&gt; boolean field.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Sign in functionality
&lt;/h3&gt;

&lt;p&gt;When users want to sign in, we will use the service we designed because we need to check if two-factor authentication is enabled and if yes, we need to send an SMS with a code. We replace the client library function with sending a request to the endpoint.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  SMS verify during sign-in functionality
&lt;/h3&gt;

&lt;p&gt;Code above runs the service for signing in and sending the SMS for verification code. Now, users need a screen to enter the SMS code. We have already created the endpoint and designed the service for this case. We need to send a request to that particular endpoint with &lt;strong&gt;code&lt;/strong&gt;, &lt;strong&gt;phone&lt;/strong&gt; &lt;strong&gt;number,&lt;/strong&gt; and &lt;strong&gt;userId&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is the code for that:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article covered adding the two-factor authentication method to our email authentication app using &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/a&gt;, &lt;a href="https://twilio.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Twilio&lt;/strong&gt;&lt;/a&gt;, and &lt;a href="https://clientapi.altogic.com/v1.3.1/modules.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Altogic Client Library&lt;/strong&gt;&lt;/a&gt;. Thanks to &lt;a href="https://altogic.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Altogic&lt;/strong&gt;&lt;/a&gt;, we can build this functionality with just a few lines of code.&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-two-factor-authentication" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; for other functionalities and the rest of the code. You can also clone it and build your app on top of it.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>react</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>How to implement Magic Link Authentication with Next.js and Altogic</title>
      <dc:creator>Mert Yerekapan</dc:creator>
      <pubDate>Thu, 05 May 2022 05:16:57 +0000</pubDate>
      <link>https://forem.com/altogic/how-to-implement-magic-link-authentication-with-nextjs-and-altogic-4dc9</link>
      <guid>https://forem.com/altogic/how-to-implement-magic-link-authentication-with-nextjs-and-altogic-4dc9</guid>
      <description>&lt;h2&gt;
  
  
  How to implement Magic Link Authentication with Next.js and Altogic
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2560%2F1%2Aq-FsWZkgNrdm9R5UYb0S6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F2560%2F1%2Aq-FsWZkgNrdm9R5UYb0S6A.png" alt="How to implement Magic Link Authentication with Next.js and Altogic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article will cover &lt;strong&gt;magic-link authentication&lt;/strong&gt; basics using Next.js and &lt;a href="https://altogic.com/" rel="noopener noreferrer"&gt;Altogic&lt;/a&gt;, a backend-as-a-service platform using its client library. This authentication method allows users to sign in to the application &lt;strong&gt;without&lt;/strong&gt; remembering their password.&lt;/p&gt;

&lt;p&gt;To reduce UX friction and avoid remembering multiple passwords, some small/medium and even large organizations are moving out from the password-based authentication flow to magic authentication, depending on their risk appetite.&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-magic-link-authentication" rel="noopener noreferrer"&gt;source code&lt;/a&gt; and &lt;a href="https://altogic-nextjs-magic-link-auth.vercel.app/" rel="noopener noreferrer"&gt;demo app&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits
&lt;/h3&gt;

&lt;p&gt;With the magic link authentication method, the user does not have to remember another password or enter it to access their account. So we can clearly understand that magic link authentication highly simplifies the login burden for users and provides a better user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;p&gt;For that authentication method, the primary condition is that the link needs to be safe and can not be able to manipulated from outside of the application. And the links should have to be used for just a few minutes and only once. So except for these conditions, a passwordless authentication seems safer than one with a password.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 If you know any other disadvantages that you discover or faced before, please write in the comments section, we would love to discuss and learn.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  How is the magic link authentication flow in Altogic?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Users who already have an account enter their email and click the “&lt;strong&gt;Send magic link&lt;/strong&gt;” button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An email with the magic link is sent to the specified email address by &lt;strong&gt;Altogic&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Users click on the link in the sent email.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Altogic redirects users to specified “&lt;strong&gt;Redirect URL&lt;/strong&gt;” with an access token in the query string parameter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This access token is used to get a session token, and users are directed to their profile page.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Youtube Promo Video
&lt;/h3&gt;

&lt;p&gt;You can check out the video below to see a live demonstration of our app.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/k4UEqFp9jFk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the project
&lt;/h2&gt;

&lt;p&gt;This project builds on top of the complete e-mail authentication app we created previously. You can follow the &lt;a href="https://medium.com/altogic/altogic-email-authentication-with-next-js-and-altogic-4c036c36ea8f" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; to build the same app or clone the project from &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-email-authentication" rel="noopener noreferrer"&gt;here&lt;/a&gt; and continue with the rest of the tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s start coding!
&lt;/h2&gt;

&lt;p&gt;We already have the &lt;strong&gt;backend&lt;/strong&gt; and &lt;strong&gt;frontend&lt;/strong&gt; of the &lt;strong&gt;email authentication now&lt;/strong&gt;. We can start implementing the &lt;strong&gt;magic link functionality&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set up the magic link page
&lt;/h3&gt;

&lt;p&gt;We need a page where we get the &lt;strong&gt;email&lt;/strong&gt; input from the user.&lt;/p&gt;

&lt;p&gt;Using the “altogic.auth.sendMagicLinkEmail(email)” we can send magic link mail to the specified email.&lt;/p&gt;

&lt;p&gt;Here is the source code of the &lt;code&gt;/auth/send-magic-link&lt;/code&gt; page:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
In the end, your screen should look like this:

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F6912%2F1%2AITH5HiwNrDfsNqZQduhp2A%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F6912%2F1%2AITH5HiwNrDfsNqZQduhp2A%402x.png" alt="Altogic send magic link screen"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Magic Link Email
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3236%2F1%2AM45W1zKshZNXswHpAp5Rpw%402x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3236%2F1%2AM45W1zKshZNXswHpAp5Rpw%402x.png" alt="Default magic link email Altogic sends"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can also change all of the message templates from the &lt;strong&gt;App settings → Authentication → Message templates&lt;/strong&gt; view of &lt;a href="https://designer.altogic.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Altogic Designer&lt;/strong&gt;&lt;/a&gt; and use &lt;strong&gt;any HTML template&lt;/strong&gt; you want.&lt;/p&gt;

&lt;p&gt;Here is how to do that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F7536%2F1%2AhwIXJvOSjdgBVsjHPo2xQg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F7536%2F1%2AhwIXJvOSjdgBVsjHPo2xQg.png" alt="Change message templates in Altogic Designer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that we sent the email, users need to click on the link to sign in.&lt;/p&gt;
&lt;h3&gt;
  
  
  Redirect URL route
&lt;/h3&gt;

&lt;p&gt;When users click on the link, &lt;strong&gt;Altogic&lt;/strong&gt; redirects to our specified Redirect URL, which is &lt;strong&gt;/auth-redirect&lt;/strong&gt; in this case.&lt;/p&gt;

&lt;p&gt;Here in &lt;strong&gt;getServerSideProps,&lt;/strong&gt; we check the query string parameters, and according to each action, we perform some actions. Here is an &lt;strong&gt;important&lt;/strong&gt; part!&lt;/p&gt;

&lt;p&gt;getAuthGrant() function either takes a session token as a parameter &lt;strong&gt;or&lt;/strong&gt; uses the one in the URL.&lt;/p&gt;

&lt;p&gt;Here, we run this code &lt;strong&gt;only on the server-side,&lt;/strong&gt; so we must &lt;strong&gt;give&lt;/strong&gt; the session token as the parameter.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  What happens if we click on the link again?
&lt;/h3&gt;

&lt;p&gt;Magic links are one-time links. If users click on the link a second time or after it expires, they get an error. This feature makes the magic link authentication method more secure.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3632%2F1%2An2vu4W04Wm2mFfVC5u9KOA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn-images-1.medium.com%2Fmax%2F3632%2F1%2An2vu4W04Wm2mFfVC5u9KOA.png" alt="Magic link url when you use it again."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see from the &lt;strong&gt;URL&lt;/strong&gt;, the access token is already used or invalid.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 You can directly insert the error message from the link for convenience.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article added the magic link authentication method to our email authentication app using &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;&lt;strong&gt;Next.js&lt;/strong&gt;&lt;/a&gt; and &lt;a href="https://clientapi.altogic.com/v1.2.2/modules.html" rel="noopener noreferrer"&gt;&lt;strong&gt;Altogic Client Library&lt;/strong&gt;&lt;/a&gt;. Thanks to &lt;a href="https://altogic.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Altogic&lt;/strong&gt;&lt;/a&gt;, we can build this functionality with just a few lines of code.&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-magic-link-authentication" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; for other functionalities and the rest of the code. You can also clone it and build your app on top of it.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Complete Email Authentication with Next.js and Altogic</title>
      <dc:creator>Mert Yerekapan</dc:creator>
      <pubDate>Mon, 25 Apr 2022 13:05:36 +0000</pubDate>
      <link>https://forem.com/altogic/complete-email-authentication-with-nextjs-and-altogic-1h1i</link>
      <guid>https://forem.com/altogic/complete-email-authentication-with-nextjs-and-altogic-1h1i</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;This article will cover email-based authentication basics using Next.js and &lt;a href="https://altogic.com" rel="noopener noreferrer"&gt;Altogic&lt;/a&gt;, a backend-as-a-service platform using its client library. This authentication method requires users to specify their email and passwords during sign-up. After signing up, users can log in to the application using their email and password. You can check the &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-email-authentication" rel="noopener noreferrer"&gt;source code&lt;/a&gt; and &lt;a href="https://altogic-nextjs-email-auth.vercel.app/" rel="noopener noreferrer"&gt;demo app&lt;/a&gt;.&lt;br&gt;
By default, email verification is &lt;strong&gt;enabled&lt;/strong&gt; in your &lt;strong&gt;App settings → Authentication&lt;/strong&gt; view of &lt;strong&gt;Altogic Designer&lt;/strong&gt;. If you would like to change this, you can &lt;strong&gt;disable&lt;/strong&gt; “Confirm email addresses” in the &lt;strong&gt;Authentication&lt;/strong&gt; view of &lt;strong&gt;Altogic Designer&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  How is the email authentication flow in Altogic?
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Users sign up with their email and password.&lt;/li&gt;
&lt;li&gt;A verification email is sent to the specified email address by Altogic.&lt;/li&gt;
&lt;li&gt;Users confirm their email by clicking on the link in the sent email.&lt;/li&gt;
&lt;li&gt;Altogic checks the token in clicked link and if valid changes the user’s email address to verified and returns an access token in the query string parameter of the redirect URL.&lt;/li&gt;
&lt;li&gt;This access token is used to get a session token and users are directed to their profile page.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Youtube Promo Video
&lt;/h3&gt;

&lt;p&gt;You can check out the video below to see a live demonstration of our app.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/rlOTW_NuJzc"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the backend
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create an app in Altogic
&lt;/h3&gt;

&lt;p&gt;First things first: To use Altogic, we need to create an app in Altogic. We can create an app in &lt;a href="https://designer.altogic.com/" rel="noopener noreferrer"&gt;Designer&lt;/a&gt; easily. All you need to do is enter a name for your app.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmm2a9cjtg0dcnb0dp83r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmm2a9cjtg0dcnb0dp83r.png" alt="How to create an application in Altogic Designer."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need &lt;code&gt;envUrl&lt;/code&gt; and &lt;code&gt;clientKey&lt;/code&gt; to access our environment via Altogic Client Library. &lt;code&gt;envUrl&lt;/code&gt; is specific to each environment, and Altogic initially creates one environment for you when you create your app. Here is how to get the &lt;code&gt;envUrl&lt;/code&gt; from environment details page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmuaxdconjc0clvu6btv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmuaxdconjc0clvu6btv.png" alt="How to get ehe environment url in Altogic Designer."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can get the &lt;code&gt;clientKey&lt;/code&gt; by clicking on the &lt;strong&gt;App Settings&lt;/strong&gt; button in the left-bottom corner of the &lt;strong&gt;Designer&lt;/strong&gt; and clicking on the &lt;strong&gt;Client library keys&lt;/strong&gt; section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqa9n7d22i23josd8no5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqa9n7d22i23josd8no5a.png" alt="Here, Altogic already created one for us, but we can create more client library keys and configure the permissions for different keys."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Users model
&lt;/h3&gt;

&lt;p&gt;By default, &lt;strong&gt;Altogic&lt;/strong&gt; creates a user model for you. You can customize it by adding different fields. Some of them are pretty advanced and customized, which is very handy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up the Frontend
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Install the packages
&lt;/h3&gt;

&lt;p&gt;Before you start to use the &lt;code&gt;npx&lt;/code&gt; command, make sure you have NodeJS installed in your development environment. Also, installing VSCode and some extensions might be better for faster development.&lt;br&gt;
💡 You can visit &lt;a href="https://nodejs.org/en/download/" rel="noopener noreferrer"&gt;https://nodejs.org/en/download/&lt;/a&gt; to &lt;strong&gt;download&lt;/strong&gt;.&lt;br&gt;
To get started, open the terminal and create a new Next.js project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx create-next-app@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Next.js will ask you to name the project. Name it whatever you want; I will use &lt;strong&gt;“altogic-email-authentication”&lt;/strong&gt; for this example. Move to the folder just created and &lt;strong&gt;install the Altogic Client Library&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;altogic-email-authentication
npm i altogic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Open the project in VSCode.&lt;br&gt;
Install &lt;strong&gt;tailwind CSS&lt;/strong&gt; and create &lt;code&gt;tailwind.config.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; tailwindcss postcss autoprefixer
npx tailwindcss init &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Add the paths to all of your template files in your &lt;code&gt;tailwind.config.js&lt;/code&gt; file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Add the following directives to your &lt;code&gt;globals.css&lt;/code&gt; file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Install &lt;strong&gt;Font Awesome&lt;/strong&gt; to use the icons.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;--save&lt;/span&gt; @fortawesome/fontawesome-svg-core
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; @fortawesome/free-solid-svg-icons
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save&lt;/span&gt; @fortawesome/react-fontawesome
npm i @fortawesome/free-brands-svg-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Install &lt;strong&gt;cookies-next&lt;/strong&gt; to set cookies for server-side rendering easily.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i cookies-next
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Install &lt;strong&gt;@headlesui/react&lt;/strong&gt; for styling.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @headlessui/react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Update the &lt;code&gt;next.config.js&lt;/code&gt; file to allow the Next.js Image component to load images from Altogic’s storage. &lt;code&gt;"c1-na.altogic.com"&lt;/code&gt; value is retrieved from the &lt;code&gt;envUrl&lt;/code&gt; which starts with &lt;code&gt;c1-na.altogic.com&lt;/code&gt; in my case.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  Set up the environment variables
&lt;/h3&gt;

&lt;p&gt;Environment variables are used to &lt;strong&gt;secure&lt;/strong&gt; your secret keys, &lt;strong&gt;reuse&lt;/strong&gt; them in different places and &lt;strong&gt;reduce&lt;/strong&gt; production mistakes. Create a &lt;code&gt;.env.localfile&lt;/code&gt; in the root directory of your application, open the file in your editor and paste the following. You can check more about environment variables in Next.js &lt;a href="https://nextjs.org/docs/basic-features/environment-variables" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Replace &lt;code&gt;YOUR-APPLICATION-ENV-URL&lt;/code&gt; and &lt;code&gt;YOUR-APPLICATION-CLIENT-KEY&lt;/code&gt; with the &lt;code&gt;envUrl&lt;/code&gt; and &lt;code&gt;clientKey&lt;/code&gt; values you retrieved while setting up your backend.&lt;br&gt;
Next, create a file to create the &lt;strong&gt;Altogic Client Library&lt;/strong&gt; instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;helpers
&lt;span class="nb"&gt;cd &lt;/span&gt;helpers
&lt;span class="nb"&gt;touch &lt;/span&gt;client.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This creates a &lt;code&gt;client.js&lt;/code&gt; file in the &lt;strong&gt;helpers directory&lt;/strong&gt;. Open the file in your editor and paste the following.&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Here, you need to enter the &lt;code&gt;envUrl&lt;/code&gt; and &lt;code&gt;clientKey&lt;/code&gt;. Optionally you can paste &lt;code&gt;signInRedirect&lt;/code&gt; to redirect your users to the specified sign-in page in some cases. This works in a way that if users try to perform a session-required action while their session has been destroyed, &lt;strong&gt;Altogic&lt;/strong&gt; redirects them to the &lt;code&gt;signInRedirect&lt;/code&gt; route.&lt;/p&gt;

&lt;h3&gt;
  
  
  Building our components
&lt;/h3&gt;

&lt;p&gt;The next step is to create the components we’ll need for our application. You can also clone our example repository and use the components right away.&lt;br&gt;
First, create a components folder with the &lt;code&gt;mkdir components&lt;/code&gt; command. Let me walk you through the components we use for our app.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Sign-in.js&lt;/code&gt; and &lt;code&gt;Sign-up.js&lt;/code&gt; file in &lt;code&gt;auth&lt;/code&gt; directory. Those are the form components we use to sign-up and sign in our users.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;EmailConfirmResend.js&lt;/code&gt; and &lt;code&gt;PasswordReset.js&lt;/code&gt; file in &lt;code&gt;auth-redirect&lt;/code&gt; directory. Those are the components we will show our users when redirected to the &lt;strong&gt;our-domain.com/auth-redirect&lt;/strong&gt; route.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AltogicBadge.js&lt;/code&gt;, &lt;code&gt;Header.js&lt;/code&gt; and &lt;code&gt;Layout.js&lt;/code&gt; file in &lt;code&gt;layout&lt;/code&gt; directory. Those are the components we use for our layout throughout the app.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SessionListItem.js&lt;/code&gt; ,&lt;code&gt;SessionList.js&lt;/code&gt; , &lt;code&gt;ProfilePhoto.js&lt;/code&gt;, &lt;code&gt;NameSection.js&lt;/code&gt; , &lt;code&gt;ChangePassword.js&lt;/code&gt; and &lt;code&gt;ChangeEmail.js&lt;/code&gt; file in &lt;code&gt;profile&lt;/code&gt; directory. Those are the components we use on the profile page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Button.js&lt;/code&gt; , &lt;code&gt;Notification.js&lt;/code&gt; and &lt;code&gt;ErrorMessage.js&lt;/code&gt; file in &lt;code&gt;ui&lt;/code&gt; directory. Those are the components we use many times to build our UI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the end, your components folder should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxgxdvo3eb4skqetafam.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxgxdvo3eb4skqetafam.png" alt="Components folder"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Let’s start coding!
&lt;/h2&gt;

&lt;p&gt;We have the backend and frontend setup ready. We can start integrating them now.&lt;/p&gt;
&lt;h3&gt;
  
  
  Some UI components we use often
&lt;/h3&gt;

&lt;p&gt;It is best to separate the logic of some of the components we use frequently and put them into a different folder to reuse.&lt;br&gt;
&lt;strong&gt;Button:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Error:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Sign up functionality with Altogic
&lt;/h3&gt;

&lt;p&gt;Altogic Client Library has a built-in function for creating new users with an email and password. You can check about it more &lt;a href="https://clientapi.altogic.com/v1.2.2/classes/AuthManager.html#signUpWithEmail" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;strong&gt;altogic&lt;/strong&gt;.auth.&lt;strong&gt;signUpWithEmail&lt;/strong&gt; takes three inputs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;email (mandatory)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;password (mandatory)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;name (optional)&lt;/strong&gt;
The code snippet handles the form input using the &lt;strong&gt;signUpWithEmail&lt;/strong&gt; function.&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Our sign-up screen should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgalq8kdm78fwtjgc5fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgalq8kdm78fwtjgc5fb.png" alt="Sign-up Screen"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This function will create a user object in your database with the provided &lt;strong&gt;email&lt;/strong&gt;, &lt;strong&gt;password&lt;/strong&gt;, and optionally &lt;strong&gt;name&lt;/strong&gt; field. Altogic will send an email to the user’s email address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Redirect URL route
&lt;/h3&gt;

&lt;p&gt;In &lt;strong&gt;Altogic&lt;/strong&gt;, you can redirect your users to a predefined route for some actions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When the user is successfully authenticated using an oAuth provider or a magic link, they will be redirected here.&lt;/li&gt;
&lt;li&gt;When the email confirmation link is clicked, they are redirected to this route.&lt;/li&gt;
&lt;li&gt;When a user changes their email, if the email confirmation setting of the app is enabled, an email is sent to them. After the user clicks it, they will be redirected to this route.&lt;/li&gt;
&lt;li&gt;When a user recovers their password, they are redirected to this route.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can check and edit this route from &lt;a href="https://designer.altogic.com/" rel="noopener noreferrer"&gt;Designer&lt;/a&gt; like below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpso888xvd0vx2fyvgpig.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpso888xvd0vx2fyvgpig.png" alt="Change REDIRECT URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here in &lt;strong&gt;getServerSideProps&lt;/strong&gt;, we check the query string parameters and according to each action, we perform some actions. Here is an &lt;strong&gt;important&lt;/strong&gt; part!&lt;/p&gt;

&lt;p&gt;&lt;code&gt;getAuthGrant()&lt;/code&gt; function either takes a session token as a parameter &lt;strong&gt;or&lt;/strong&gt; uses the one in the URL.&lt;/p&gt;

&lt;p&gt;In the example below, &lt;strong&gt;Altogic&lt;/strong&gt; sent the user an &lt;strong&gt;email confirmation&lt;/strong&gt; mail. When clicked, it redirects to our specified &lt;strong&gt;Redirect URL&lt;/strong&gt;, which is &lt;strong&gt;auth-redirect&lt;/strong&gt;. &lt;br&gt;
There are three query parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;status=200&lt;/strong&gt; indicates that Altogic managed to send me a valid token for my operation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;access_token&lt;/strong&gt; gives us the token value I am going to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;action=email-confirm&lt;/strong&gt; indicates for which action I am going to use this token. In this case, it is confirming my email.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbvze4hqlmpi4ktowi18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcbvze4hqlmpi4ktowi18.png" alt="Access token as query string parameter"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we run this code &lt;strong&gt;only on the server-side&lt;/strong&gt;, so we must &lt;strong&gt;give&lt;/strong&gt; the session token as the parameter.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Sign in functionality with Altogic
&lt;/h3&gt;

&lt;p&gt;Altogic Client Library also has a built-in function for signing in users. You can check about it more &lt;a href="https://clientapi.altogic.com/v1.2.2/classes/AuthManager.html#signInWithEmail" rel="noopener noreferrer"&gt;here&lt;/a&gt;. The code snippet handles the form input using the &lt;strong&gt;signInWithEmail&lt;/strong&gt; function.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;altogic&lt;/strong&gt;.auth.&lt;strong&gt;signInWithEmail&lt;/strong&gt; takes two inputs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;email&lt;/strong&gt; (&lt;strong&gt;mandatory&lt;/strong&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;password&lt;/strong&gt; (&lt;strong&gt;mandatory&lt;/strong&gt;)&lt;/li&gt;
&lt;/ol&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see in the code above, we are sending a &lt;strong&gt;POST&lt;/strong&gt; request to &lt;strong&gt;/api/login&lt;/strong&gt; route. We are doing this to set the cookie for &lt;strong&gt;server-side rendering&lt;/strong&gt; (SSR). If you are not going to use &lt;strong&gt;SSR&lt;/strong&gt;, you can delete these lines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do we need cookies for SSR?
&lt;/h3&gt;

&lt;p&gt;One of the key features of Next.js is &lt;strong&gt;server-side rendering&lt;/strong&gt;. Meaning that some of the code will run &lt;strong&gt;only&lt;/strong&gt; on the server and &lt;strong&gt;not&lt;/strong&gt; on the client side. But session and user information is stored on the &lt;strong&gt;client-side&lt;/strong&gt;. How do we understand if &lt;strong&gt;we have a user authenticated&lt;/strong&gt; when a request is made to the server? For this purpose, we need to &lt;strong&gt;set a cookie&lt;/strong&gt; on the server-side when we sign in and &lt;strong&gt;delete it&lt;/strong&gt; when we sign out. This way, we can check if the user is authenticated on the server-side and then perform the actions we want.&lt;br&gt;
Here is the code you need to add to your &lt;strong&gt;api/login&lt;/strong&gt; folder:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
&lt;br&gt;
On any page, we can check if there is a user signed in or not. This part is needed both for route protection and fetching data special to the user with SSR.

&lt;p&gt;Our sign-in screen should look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftall7kmugko5ur2bysdc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftall7kmugko5ur2bysdc.png" alt="Sign-in Page"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  How to check if there is a user authenticated via SSR?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;getServerSideProps&lt;/strong&gt; function runs every time the user makes a request. It runs &lt;strong&gt;only&lt;/strong&gt; on the server, and its content is not exposed to the client. We check if a user is authenticated and redirect them to their profile or sign-in page accordingly.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Signout users
&lt;/h3&gt;

&lt;p&gt;Here is the page you can redirect your users to log them out. It simply invalidates the session, clears the context, and sends a &lt;strong&gt;POST&lt;/strong&gt; request to &lt;strong&gt;our-domain/api/logout&lt;/strong&gt; to clear the cookies.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When we sign out, we need to &lt;strong&gt;delete&lt;/strong&gt; the cookie we set on the &lt;strong&gt;server-side&lt;/strong&gt; because the token value in the cookie is &lt;strong&gt;no longer valid&lt;/strong&gt;.&lt;br&gt;
Here is the code you need to add to your &lt;strong&gt;api/logout&lt;/strong&gt; file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Storing user information in context
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;UserContext&lt;/code&gt; creates a context and sets the user and session property null by default. To learn more about context and how to effectively use them, read &lt;a href="https://reactjs.org/docs/context.html" rel="noopener noreferrer"&gt;React’s documentation on context&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  More features
&lt;/h3&gt;

&lt;p&gt;Our example application covers more features like uploading a profile picture, managing sessions, password recovery, password change, and email change. You can check all of them in the repository. Here, I just want to show you how easily you can implement them with client library functions.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we built a simple yet capable email authentication app using &lt;strong&gt;Next.js&lt;/strong&gt; and &lt;strong&gt;Altogic Client Library&lt;/strong&gt;. Generally, building authentication is one of the most challenging parts of app development. Thanks to &lt;strong&gt;Altogic&lt;/strong&gt;, we can build this functionality with just a few lines of code.&lt;br&gt;
You can check out the &lt;a href="https://github.com/altogic/altogic/tree/main/examples/nextjs-email-authentication" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt; for other functionalities and the rest of the code. You can also clone it and build your app on top of it.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>altogic</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
