<?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: karabo seeisa</title>
    <description>The latest articles on DEV Community by karabo seeisa (@thesbd).</description>
    <link>https://dev.to/thesbd</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%2F2552233%2F9e267e88-6b83-4ed7-9f8a-fffbab915df7.png</url>
      <title>DEV Community: karabo seeisa</title>
      <link>https://dev.to/thesbd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thesbd"/>
    <language>en</language>
    <item>
      <title>Building a Secure Auth System in Express (JWT, Redis, Refresh Tokens, and RBAC) and Automating It with a CLI</title>
      <dc:creator>karabo seeisa</dc:creator>
      <pubDate>Sat, 04 Apr 2026 07:46:19 +0000</pubDate>
      <link>https://dev.to/thesbd/building-a-secure-auth-system-in-express-jwt-redis-refresh-tokens-and-rbac-and-automating-it-4o0h</link>
      <guid>https://dev.to/thesbd/building-a-secure-auth-system-in-express-jwt-redis-refresh-tokens-and-rbac-and-automating-it-4o0h</guid>
      <description>&lt;p&gt;Authentication in Express applications is often underestimated.&lt;/p&gt;

&lt;p&gt;Most implementations stop at “generate a JWT and verify it,” but real-world systems require much more:&lt;/p&gt;

&lt;p&gt;• Refresh token rotation&lt;/p&gt;

&lt;p&gt;• Token invalidation&lt;/p&gt;

&lt;p&gt;• Concurrency safety&lt;/p&gt;

&lt;p&gt;• Role-based access control (RBAC)&lt;/p&gt;

&lt;p&gt;• Stateful tracking (usually via Redis)&lt;/p&gt;

&lt;p&gt;After building this stack multiple times, I decided to formalise it into a reusable system and eventually a CLI that scaffolds it in seconds.&lt;/p&gt;

&lt;p&gt;This post breaks down the architecture behind it and how you can use it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem with Typical JWT Auth
&lt;/h2&gt;

&lt;p&gt;A basic JWT setup usually looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;TypeScript&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;15m&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works for simple cases, but breaks down quickly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;No Token Revocation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Once issued, a JWT is valid until it expires.&lt;/p&gt;

&lt;p&gt;You can’t easily invalidate it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Stateless Refresh = Security Risk&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If refresh tokens are not tracked, they can be reused indefinitely.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Concurrency Issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If two refresh requests happen at the same time:&lt;/p&gt;

&lt;p&gt;both can succeed&lt;/p&gt;

&lt;p&gt;multiple valid tokens are created&lt;/p&gt;

&lt;p&gt;This leads to token duplication and potential session abuse.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Architecture I Settled On
&lt;/h2&gt;

&lt;p&gt;To solve these issues&lt;br&gt;
, the system uses:&lt;/p&gt;

&lt;p&gt;Access Tokens (JWT)&lt;/p&gt;

&lt;p&gt;• Short-lived (e.g. 15 minutes)&lt;/p&gt;

&lt;p&gt;• Used for API authentication&lt;/p&gt;

&lt;p&gt;• Stateless verification&lt;/p&gt;

&lt;p&gt;Refresh Tokens (Stateful)&lt;/p&gt;

&lt;p&gt;• Stored in Redis&lt;/p&gt;

&lt;p&gt;• Rotated on every use&lt;/p&gt;

&lt;p&gt;• Old tokens are invalidated&lt;/p&gt;

&lt;p&gt;This gives you control over sessions.&lt;/p&gt;


&lt;h2&gt;
  
  
  Redis as a Token Store
&lt;/h2&gt;

&lt;p&gt;Redis acts as the source of truth for refresh tokens:&lt;/p&gt;

&lt;p&gt;• Track active sessions&lt;/p&gt;

&lt;p&gt;• Invalidate tokens instantly&lt;/p&gt;

&lt;p&gt;• Enforce single-use refresh tokens&lt;/p&gt;


&lt;h2&gt;
  
  
  Refresh Token Rotation
&lt;/h2&gt;

&lt;p&gt;Every refresh request:&lt;/p&gt;

&lt;p&gt;• Verifies the token&lt;/p&gt;

&lt;p&gt;• Checks Redis for validity&lt;/p&gt;

&lt;p&gt;• Deletes the old token&lt;/p&gt;

&lt;p&gt;• Issues a new refresh token&lt;/p&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;p&gt;A refresh token can only be used once.&lt;/p&gt;


&lt;h2&gt;
  
  
  Concurrency Safety
&lt;/h2&gt;

&lt;p&gt;A key problem is handling simultaneous refresh requests.&lt;/p&gt;

&lt;p&gt;Solution:&lt;/p&gt;

&lt;p&gt;• Atomic operations in Redis&lt;/p&gt;

&lt;p&gt;• Only one request can invalidate + rotate&lt;/p&gt;

&lt;p&gt;• The second request fails with 401&lt;/p&gt;

&lt;p&gt;This prevents replay attacks and token duplication.&lt;/p&gt;


&lt;h2&gt;
  
  
  RBAC (Role-Based Access Control)
&lt;/h2&gt;

&lt;p&gt;Authentication is not enough , you also need authorization.&lt;/p&gt;

&lt;p&gt;Example middleware:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;TypeScript&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requireAdmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Admin only&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures only users with the correct role can access protected routes.&lt;/p&gt;

&lt;p&gt;Putting It Together&lt;br&gt;
The system exposes a simple interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;TypeScript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;createAuthenik8&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;

&lt;span class="na"&gt;jwtSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="na"&gt;refreshSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REFRESH_SECRET&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From there:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;signToken()&lt;/code&gt; → access tokens&lt;/p&gt;

&lt;p&gt;&lt;code&gt;generateRefreshToken()&lt;/code&gt; → refresh tokens&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Refresh token()&lt;/code&gt; → rotation logic&lt;/p&gt;

&lt;p&gt;&lt;code&gt;requireAdmin&lt;/code&gt; → RBAC middleware&lt;/p&gt;

&lt;p&gt;Automating the Setup&lt;br&gt;
After building this repeatedly, I created a CLI to remove the setup step entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Bash

npx create-authenik8-app my-app

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates:&lt;/p&gt;

&lt;p&gt;• Express + TypeScript project&lt;/p&gt;

&lt;p&gt;• JWT + refresh token system&lt;/p&gt;

&lt;p&gt;• Redis integration&lt;/p&gt;

&lt;p&gt;•RBAC middleware&lt;/p&gt;

&lt;p&gt;• Preconfigured routes&lt;/p&gt;

&lt;p&gt;You can go from zero → running auth server in minutes.&lt;/p&gt;

&lt;p&gt;Why Redis is Required&lt;br&gt;
A common question is: “Why not keep everything stateless?”&lt;/p&gt;

&lt;p&gt;Because:&lt;/p&gt;

&lt;p&gt;• You can’t revoke tokens&lt;/p&gt;

&lt;p&gt;• You can’t prevent reuse&lt;/p&gt;

&lt;p&gt;• You can’t track sessions&lt;/p&gt;

&lt;p&gt;Redis enables:&lt;/p&gt;

&lt;p&gt;• Immediate invalidation&lt;/p&gt;

&lt;p&gt;• Session tracking&lt;/p&gt;

&lt;p&gt;• Single-use refresh tokens&lt;/p&gt;


&lt;h2&gt;
  
  
  Trade-offs
&lt;/h2&gt;

&lt;p&gt;This approach introduces:&lt;/p&gt;

&lt;p&gt;• External dependency (Redis)&lt;/p&gt;

&lt;p&gt;• Slight complexity increase&lt;/p&gt;

&lt;p&gt;• Network latency for token validation&lt;/p&gt;

&lt;p&gt;But in exchange, you get:&lt;/p&gt;

&lt;p&gt;• Proper session control&lt;/p&gt;

&lt;p&gt;• Stronger security guarantees&lt;/p&gt;

&lt;p&gt;• Predictable auth behavior&lt;/p&gt;


&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Authentication is one of those systems that seems simple until it isn’t.&lt;/p&gt;

&lt;p&gt;The difference between a basic implementation and a production-ready one is:&lt;/p&gt;

&lt;p&gt;• handling edge cases&lt;/p&gt;

&lt;p&gt;• controlling state&lt;/p&gt;

&lt;p&gt;• preventing abuse&lt;/p&gt;

&lt;p&gt;This project started as a way to standardize those decisions and avoid rewriting the same logic repeatedly.&lt;/p&gt;

&lt;p&gt;If you’ve built auth systems before, I’d be interested in how you approach:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;refresh token handling&lt;/li&gt;
&lt;li&gt;revocation strategies&lt;/li&gt;
&lt;li&gt;concurrency edge cases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Links:&lt;br&gt;
Authenik8 site:&lt;a href="https://authenik8.vercel.app/" rel="noopener noreferrer"&gt;https://authenik8.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Gitlab: &lt;a href="https://gitlab.com/COD434/create-authenik8-app" rel="noopener noreferrer"&gt;https://gitlab.com/COD434/create-authenik8-app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tiktok: &lt;a href="https://www.tiktok.com/@thesbd8?%5C_r=1&amp;amp;%5C_t=ZS-9577WVfucT4" rel="noopener noreferrer"&gt;https://www.tiktok.com/@thesbd8?\_r=1&amp;amp;\_t=ZS-9577WVfucT4&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try It&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Bash

npx create-authenik8-app my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Closing
&lt;/h2&gt;

&lt;p&gt;If you’re working with Express and need a solid starting point for authentication, this should save you a significant amount of setup time.&lt;/p&gt;

&lt;p&gt;Feedback is welcome.&lt;/p&gt;

</description>
      <category>api</category>
      <category>redis</category>
      <category>buildinpublic</category>
      <category>architecture</category>
    </item>
    <item>
      <title>RabbitMQ: The Superhero My API Didn’t Know It Needed</title>
      <dc:creator>karabo seeisa</dc:creator>
      <pubDate>Mon, 28 Jul 2025 13:20:16 +0000</pubDate>
      <link>https://dev.to/thesbd/rabbitmq-the-superhero-my-api-didnt-know-it-needed-njp</link>
      <guid>https://dev.to/thesbd/rabbitmq-the-superhero-my-api-didnt-know-it-needed-njp</guid>
      <description>&lt;p&gt;&lt;strong&gt;The Problem: Hanging Requests, Delivered Emails&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In my Node.js API, users register and receive a verification email. Simple, right?&lt;/p&gt;

&lt;p&gt;But something strange kept happening:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The email would be sent&lt;/li&gt;
&lt;li&gt;But the HTTP request would hang&lt;/li&gt;
&lt;li&gt;The client got no response&lt;/li&gt;
&lt;li&gt;My logs showed timeouts&lt;/li&gt;
&lt;li&gt;And eventually… crashed sockets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After digging, I realized:&lt;/p&gt;

&lt;p&gt;The SMTP email-sending process was blocking the main thread just long enough to let the HTTP connection time out.&lt;/p&gt;

&lt;p&gt;This was a race condition: my API was waiting for the SMTP server to respond, while the client’s connection was waiting for me.&lt;/p&gt;




&lt;p&gt;The Insight: Decouple the Work&lt;/p&gt;

&lt;p&gt;I realized I was making the email-sending part synchronous, tying the API response to something slow (SMTP).&lt;/p&gt;

&lt;p&gt;That’s when I remembered the concept of queuing so I did some research and found that personally I liked RabbitMQ.&lt;/p&gt;




&lt;p&gt;How I Fixed This Issue&lt;/p&gt;

&lt;p&gt;Here’s what I did:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; The /register route publishes a message to a RabbitMQ queue (emailQueue)&lt;/li&gt;
&lt;li&gt; A separate email worker subscribes to the queue&lt;/li&gt;
&lt;li&gt; The worker handles the SMTP email process asynchronously&lt;/li&gt;
&lt;li&gt; Meanwhile, the API responds immediately to the client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Here's What Achieved:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No more hanging sockets&lt;/li&gt;
&lt;li&gt; Emails still go out&lt;/li&gt;
&lt;li&gt; Race condition avoided&lt;/li&gt;
&lt;li&gt;Clean separation of concerns&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Why I Chose RabbitMQ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I could’ve tried background threads or retry logic. But RabbitMQ gave me:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Message durability&lt;/li&gt;
&lt;li&gt;Retry control&lt;/li&gt;
&lt;li&gt;A proper job queue&lt;/li&gt;
&lt;li&gt;A decoupled architecture I can scale later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And now, I can apply this same technique for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Password resets&lt;/li&gt;
&lt;li&gt;Event logs&lt;/li&gt;
&lt;li&gt;Audit trails&lt;/li&gt;
&lt;li&gt;Even SMS messages or 2FA &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Call me a nerd but I think that's cool.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Implementation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the publisher - gets the request to send a verification email, drops it into a queue, and the worker handles the rest . simple, fast, and scalable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const publishToQueue = async (queue: string, message: any)=&amp;gt;{
if(!channel)
throw new Error("RabbitMQ channel not initialized");
channel.sendToQueue(queue,Buffer.from(JSON.stringify(message)),{persistent: true});
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the worker - It consumes messages form the queue and sends the email asynchronously,without delaying the HTTP response to the client .&lt;/p&gt;

&lt;p&gt;That means users don't wait around for an email to send = much better UX if you ask me&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;channel.consume("emailQueue",async (msg) =&amp;gt;{
if(msg !== null){
const {email,verifyToken} = JSON.parse(msg.content.toString())
await sendVerificationEmail(email,verifyToken);
channel.ack(msg)
}
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your API does more than just respond to users — like sending emails or talking to 3rd parties — don’t make it wait.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;RabbitMQ helped me move that responsibility out of the request cycle and made my code faster, safer, and easier to maintain.&lt;/p&gt;

&lt;p&gt;I also plan to use it in the near future.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Let’s Connect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Have you hit similar issues in your backend? let me know how you tackled async tasks or race conditons.&lt;/p&gt;

&lt;p&gt;Here's how I implemented it might spark something in your project :&lt;a href="//www.github.com/COD434/Authenik8"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
    <item>
      <title>A Plug and Play Auth API</title>
      <dc:creator>karabo seeisa</dc:creator>
      <pubDate>Sun, 13 Jul 2025 14:39:58 +0000</pubDate>
      <link>https://dev.to/thesbd/a-plug-and-play-auth-api-59bi</link>
      <guid>https://dev.to/thesbd/a-plug-and-play-auth-api-59bi</guid>
      <description>&lt;p&gt;From "Simple Form" to Full Pure Backend Auth API—Here’s What I Learned  &lt;/p&gt;

&lt;p&gt;I thought building a form would be easy. Spoiler: I was wrong.  &lt;/p&gt;

&lt;p&gt;What started as a basic CRUD app quickly spiraled into a deep dive into:&lt;br&gt;&lt;br&gt;
✔️ Token-based authentication (JWT)&lt;br&gt;&lt;br&gt;
✔️ Password hashing &amp;amp; encryption&lt;br&gt;&lt;br&gt;
✔️ Role-based access control&lt;/p&gt;

&lt;p&gt;✔️ Redis-rate-limiting&lt;br&gt;
And some other cool features&lt;/p&gt;

&lt;p&gt;Turns out, the "Login with Google" button I mindlessly click every day? Way more complex under the hood. &lt;/p&gt;

&lt;p&gt;I built this Auth API to demystify the process with security, docs, and scalability in mind. Perfect for devs who:&lt;br&gt;&lt;br&gt;
🔹 Want to see auth workflows stripped bare&lt;br&gt;&lt;br&gt;
🔹 Need a reference for their next project  &lt;/p&gt;

&lt;p&gt;Check it out &amp;amp; roast my code: (&lt;a href="https://github.com/COD434/Auth-System-API" rel="noopener noreferrer"&gt;https://github.com/COD434/Auth-System-API&lt;/a&gt;)  &lt;/p&gt;

&lt;p&gt;Question for you:&lt;br&gt;
What’s the most "simple" feature that surprised you with its complexity?  &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
      <category>backend</category>
      <category>node</category>
    </item>
  </channel>
</rss>
