<?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: Herve Tribouilloy</title>
    <description>The latest articles on DEV Community by Herve Tribouilloy (@digitalrisedorset).</description>
    <link>https://dev.to/digitalrisedorset</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%2F1959025%2F93999a34-e507-41d8-b1a3-3cdc4ad4804a.png</url>
      <title>DEV Community: Herve Tribouilloy</title>
      <link>https://dev.to/digitalrisedorset</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/digitalrisedorset"/>
    <language>en</language>
    <item>
      <title>OAuth Login Flow with Vite</title>
      <dc:creator>Herve Tribouilloy</dc:creator>
      <pubDate>Sat, 07 Feb 2026 15:27:29 +0000</pubDate>
      <link>https://dev.to/digitalrisedorset/oauth-login-flow-with-vite-n98</link>
      <guid>https://dev.to/digitalrisedorset/oauth-login-flow-with-vite-n98</guid>
      <description>&lt;p&gt;This article illustrates an implementation of an &lt;strong&gt;OAuth login flow&lt;/strong&gt; using &lt;strong&gt;Vite&lt;/strong&gt; as a JavaScript frontend. It highlights a &lt;strong&gt;server-side solution&lt;/strong&gt; required to securely persist the session cookie when working with a pure client-side framework like Vite.&lt;/p&gt;

&lt;p&gt;The example uses Google as the login provider and Passport to handle authentication.&lt;/p&gt;

&lt;p&gt;Below is a snapshot of the core components involved in the OAuth flow and how responsibilities are split between them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Faqkgonj02wwy42plkf7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Faqkgonj02wwy42plkf7j.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Although the OAuth flow above is well known, I discovered a practical limitation when using Vite.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because a Vite application is a static frontend that runs entirely in the browser, it cannot handle a JWT server-side or create an HTTP-only session cookie. Establishing a secure session therefore requires a server that can receive the token and set the cookie in the HTTP response.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To handle this, I currently use a thin  Express service that receives the JWT and sets it as a secure cookie before redirecting the user back to the Vite application. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The essential requirement is the domain:&lt;/strong&gt; the server that sets the cookie must share the same parent domain as the Vite host. For example, a service running on auth.reactedge.net can set a cookie for .reactedge.net, which will then be sent automatically to wpdemo.reactedge.net.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The GitHub repository contains the flow illustrated here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/digitalrisedorset/bookme" rel="noopener noreferrer"&gt;https://github.com/digitalrisedorset/bookme&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The oauth-express folder implements the Google OAuth strategy. After successful authentication, it creates a JWT and synchronises the user with the backend.&lt;/p&gt;

&lt;p&gt;The auth-bridge is the thin Express service that receives this JWT, sets it as a secure HTTP-only cookie for the browser, and then redirects the user back to the Vite frontend. This allows the session to persist without exposing the token to client-side code.&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>jwt</category>
      <category>logincookie</category>
    </item>
    <item>
      <title>Implementing Login in a Next.js App with Passport, JWT, and DDD</title>
      <dc:creator>Herve Tribouilloy</dc:creator>
      <pubDate>Sun, 01 Feb 2026 10:01:14 +0000</pubDate>
      <link>https://dev.to/digitalrisedorset/implementing-login-in-a-nextjs-app-with-passport-jwt-and-ddd-2loe</link>
      <guid>https://dev.to/digitalrisedorset/implementing-login-in-a-nextjs-app-with-passport-jwt-and-ddd-2loe</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;I originally built a Next.js application that required a login feature.&lt;br&gt;
From the start, I wanted this login to support OAuth to improve user convenience and avoid reinventing authentication flows.&lt;/p&gt;

&lt;p&gt;To do this properly, I chose Passport (a well-established authentication library) and used JWTs as the security artefact for authenticated identity.&lt;/p&gt;

&lt;p&gt;So far, this is fairly standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  A deliberate DDD split
&lt;/h2&gt;

&lt;p&gt;Where this became interesting is that I wanted the application to follow Domain-Driven Design (DDD) principles.&lt;/p&gt;

&lt;p&gt;Instead of letting authentication live “wherever it was convenient”, I explicitly split the system into &lt;strong&gt;three components&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;
Responsible for data persistence and business rules
(API / GraphQL, user model, permissions, session validity)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAuth Express server&lt;/strong&gt;
A custom Express server that owns Passport entirely
(strategies, login orchestration, token issuance)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;
A Next.js application responsible only for UI and user interaction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;OAuth Express server&lt;br&gt;
A custom Express server that owns Passport entirely&lt;br&gt;
(strategies, login orchestration, token issuance)&lt;/p&gt;

&lt;p&gt;This separation had a very clear goal:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Authentication should be reusable independently of the frontend technology.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;With this setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The frontend could change&lt;/li&gt;
&lt;li&gt;The backend could change&lt;/li&gt;
&lt;li&gt;OAuth could be reused across projects&lt;/li&gt;
&lt;li&gt;without rewriting the login logic or coupling Passport to a specific UI framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So far, this architecture worked well.&lt;/p&gt;

&lt;h2&gt;
  
  
  The subtle convenience of Next.js
&lt;/h2&gt;

&lt;p&gt;Next.js, however, has a unique property:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It runs both on the server and in the browser.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This creates a powerful shortcut.&lt;/p&gt;

&lt;p&gt;In this architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Next.js can call the OAuth server server-side&lt;/li&gt;
&lt;li&gt;Receive the JWT outside the browser&lt;/li&gt;
&lt;li&gt;Then forward that JWT to the client and store it in a cookie&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From a developer perspective, this feels elegant and simple.&lt;/p&gt;

&lt;p&gt;But architecturally, something subtle is happening:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The frontend is now participating in authentication storage.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though Passport lives elsewhere, Next.js becomes part of the trust boundary, because it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;receives the JWT server-side&lt;/li&gt;
&lt;li&gt;decides how it is persisted in the browser&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Next.js is a powerful environment.&lt;/p&gt;

&lt;p&gt;Its ability to run code both server-side and client-side makes it well suited for implementing authentication flows. In this architecture, Next.js can safely receive a JWT on the server and persist it in the browser as a cookie within a single execution path.&lt;/p&gt;

&lt;p&gt;By applying Domain-Driven Design, authentication logic lives outside the frontend instead of being buried inside a single framework. This keeps responsibilities clear and boundaries explicit, while still allowing the frontend to take advantage of Next.js’s capabilities.&lt;/p&gt;

&lt;p&gt;The important takeaway is that the login feature is only part of the result. By separating concerns, two out of three components can now be reused unchanged in another project — something I’ll explore in a follow-up article.&lt;/p&gt;

&lt;p&gt;If you’d like to explore this architecture in practice, the OAuth component described in this article is available as a public repository:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/digitalrisedorset/oauth-signin" rel="noopener noreferrer"&gt;https://github.com/digitalrisedorset/oauth-signin&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository contains the standalone OAuth Express server that owns the Passport implementation and JWT issuance, exactly as described above. It’s designed to be reused across projects, independently of the frontend framework.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>security</category>
    </item>
  </channel>
</rss>
