<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DavidRnR</title>
    <description>The latest articles on DEV Community by DavidRnR (@davidrnr).</description>
    <link>https://dev.to/davidrnr</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F179546%2F81ad17a1-c69b-49b3-ab24-e9d4d2ca839c.jpg</url>
      <title>DEV Community: DavidRnR</title>
      <link>https://dev.to/davidrnr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/davidrnr"/>
    <language>en</language>
    <item>
      <title>Angular Smart Interceptor — Queue of Requests</title>
      <dc:creator>DavidRnR</dc:creator>
      <pubDate>Wed, 12 Jun 2019 14:44:09 +0000</pubDate>
      <link>https://dev.to/davidrnr/angular-smart-interceptor-queue-of-requests-13de</link>
      <guid>https://dev.to/davidrnr/angular-smart-interceptor-queue-of-requests-13de</guid>
      <description>&lt;h3&gt;Hi everyone! My name is David Martín and I’m from Argentina.&lt;/h3&gt;

&lt;h3&gt;Let’s create a Smart Interceptor with JWT Auth and list some Programming Languages and Operatives System, using Access Token, Refresh Token, and Queue of Requests.&lt;/h3&gt;

&lt;p&gt;I created a Backend- NodeJS + MongoDB with the next endpoints:&lt;br&gt;
/api/auth/signin&lt;/p&gt;

&lt;p&gt;/api/auth/token&lt;/p&gt;

&lt;p&gt;/api/app/programmingLang (Access Token required)&lt;/p&gt;

&lt;p&gt;/api/app/os (Access Token required)&lt;/p&gt;

&lt;p&gt;I’ve build a simple Angular App with a Login Page and a Home Page. By the way, I’m using Angular Material.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/smart-interceptor" rel="noopener noreferrer"&gt;Here is the live demo in Stackblitz.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4qle9v182qlnvoi1dby.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp4qle9v182qlnvoi1dby.png" alt="Login page" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu87sz09bn4mz2ynepp35.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu87sz09bn4mz2ynepp35.png" alt="Tables Page" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m not gonna talk about build the APP, only the Interceptor. But a quick view about Login is, when the User sing in, the app saves in the localStorage of the browser an access_token and a refresh_token. Then the APP can handle the auth in the router with canActivate and the service AuthGuard.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7k99zeer8c5xvm67v71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy7k99zeer8c5xvm67v71.png" alt="Router" width="684" height="501"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;PLs (Programming Languages) and OSs (Operative Systems) need auth. So those requests need the Access Token. Let’s create an Interceptor and add the Access Token to every request.&lt;/p&gt;

&lt;p&gt;I created a new folder /helper with these two files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tft6vb69ordfaclfgb9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3tft6vb69ordfaclfgb9.png" alt="Helper folder" width="285" height="446"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;“Main Interceptor” gonna add the Access Token to every request.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvpkt9yqrn8wn7bvw2nt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvpkt9yqrn8wn7bvw2nt.png" alt="Main Interceptor" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the Interceptor to the AppModule, app.module.ts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9upzo5xgrnmb0h696gv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9upzo5xgrnmb0h696gv.png" alt="Import Interceptor" width="790" height="96"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwrtp29ulx7uhdyesyar.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzwrtp29ulx7uhdyesyar.png" alt="Import Interceptor" width="795" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;What happens when the Access Token expires?&lt;/h3&gt;

&lt;p&gt;The Access Token has got a time expiration. Then, the next request gonna fails (401 error).&lt;/p&gt;

&lt;p&gt;With the Refresh Token the App can get a new Access Token calling the endpoint /api/auth/token.&lt;/p&gt;

&lt;p&gt;Home Page load PLs and OSs, two requests. Now, if PLs fails (401 error) we can get a new Acces Token. But…&lt;/p&gt;

&lt;p&gt;How to handle the other request?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Error Interceptor needs a Queue. For example, imagine an App with 6 requests in one Page. The first one fails (401 error), Error Interceptor tries to get the new Access Token, but at the same time, the other 5 requests fail as well. So those 5 requests need to wait for the new token and then try again.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Services in Angular are a singleton (One instance). When the Interceptor is trying to get the new Access Token, the variable “static accessTokenError” handle the status.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvejxwobxyhwxoow3hla.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkvejxwobxyhwxoow3hla.png" alt="Error Interceptor" width="800" height="321"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Build the body with the refresh token and try to get the new tokens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgtz4qpwstlxbu7yiq3z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgtz4qpwstlxbu7yiq3z.png" alt="Error Interceptor" width="800" height="689"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When &lt;em&gt;“ErrorInterceptor.accessTokenError is true”&lt;/em&gt; call a method to keep waiting for the request until getting the new Access Token.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foutkkjaw4vis8ckp7g71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foutkkjaw4vis8ckp7g71.png" alt="Error Interceptor" width="648" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ve mixed Observables with vanilla JS because to me, it was better without subscribing any function, etc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can test this Demo with, &lt;a href="mailto:test@test.com"&gt;test@test.com&lt;/a&gt; 1234test&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After login, open DevTools, go to Application, change the access_token and refresh the page. Check the Network tab.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/smart-interceptor" rel="noopener noreferrer"&gt;Here is the live demo in Stackblitz.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>interceptor</category>
    </item>
  </channel>
</rss>
