<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom" -->

---
title: Add OAuth 2.0 to a Node.js CRUD app | daily.dev
description: A step-by-step tutorial extends a previous Node.js CRUD vinyl-record app by replacing the ngrok CLI agent with the ngrok JavaScript SDK, setting up a stable...
canonical: https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Add OAuth 2.0 to a Node.js CRUD app | daily.dev
og:description: A step-by-step tutorial extends a previous Node.js CRUD vinyl-record app by replacing the ngrok CLI agent with the ngrok JavaScript SDK, setting up a stable...
og:url: https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom
og:image: https://api.daily.dev/og/posts/BiM8YbSoM.png
og:image:alt: Add OAuth 2.0 to a Node.js CRUD app
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Add OAuth 2.0 to a Node.js CRUD app

**[ngrok Blog](https://daily.dev/sources/ngrok)** · 9 min read · 0 upvotes · 0 comments

## Summary

A step-by-step tutorial extends a previous Node.js CRUD vinyl-record app by replacing the ngrok CLI agent with the ngrok JavaScript SDK, setting up a stable static domain, and adding Google OAuth 2.0 to authenticate and authorize users. It covers serving the React build from Express, configuring an ngrok session and listener in code, restricting access by email or domain, and adding a graceful SIGINT shutdown handler.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://ngrok.com/blog/nodejs-crud-app-oauth-tutorial>

## Questions this post answers

### How do I add Google OAuth authentication to my Node.js app using ngrok?

Add the .oauth("google") method to the ngrok listener object, calling it after .domain() and before .listen(). This requires all incoming requests, including those to the React frontend and REST API, to authenticate with Google OAuth. You can restrict access further by passing allowed domains or specific email addresses as arguments to the oauth() function.

_See how daily.dev surfaces practical OAuth and ngrok integration walkthroughs for shipping secure Node.js apps._

### Why should I use the ngrok JavaScript SDK instead of the ngrok CLI agent for production apps?

The ngrok CLI agent assigns a random domain that changes every session, which works for local testing but breaks OAuth setups requiring a stable redirect URL. The ngrok JavaScript SDK lets you define ingress directly in code with a static domain, such as spin-vinyl-js.ngrok.io, so the domain stays consistent across restarts and environments.

_Developers weighing ingress tooling choices track comparisons like this on daily.dev before locking in an architecture._

## Similar posts on daily.dev

- [Twitter Login Using Node and MySQL](https://daily.dev/posts/twitter-login-using-node-and-mysql-broysf37w) · Planet MySQL · 0 upvotes · 0 comments
- [An Introduction to OAuth 2](https://daily.dev/posts/an-introduction-to-oauth-2-4iox2hqnk) · DigitalOcean Community · 0 upvotes · 0 comments
- [How OAuth works: GitHub and Google login explained](https://daily.dev/posts/how-oauth-works-github-and-google-login-explained-z7bhexnib) · Flavio Copes · 1 upvotes · 0 comments
- [What Programmatic Onboarding Looks Like When the Gateway Is Tyk](https://daily.dev/posts/what-programmatic-onboarding-looks-like-when-the-gateway-is-tyk-xu3evqr2x) · API Evangelist · 1 upvotes · 0 comments

---

Tags: [#react](https://daily.dev/tags/react), [#devtools](https://daily.dev/tags/devtools), [#nodejs](https://daily.dev/tags/nodejs), [#authentication](https://daily.dev/tags/authentication), [#oauth](https://daily.dev/tags/oauth)

[View this post on daily.dev](https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Add OAuth 2.0 to a Node.js CRUD app","url":"https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom"},"datePublished":"2026-08-23T07:21:30.951Z","dateModified":"2026-08-23T07:26:28.191Z","description":"A step-by-step tutorial extends a previous Node.js CRUD vinyl-record app by replacing the ngrok CLI agent with the ngrok JavaScript SDK, setting up a stable...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ca4d6a2c5d15df560f73c862bf43d5d6?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/ca4d6a2c5d15df560f73c862bf43d5d6?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"ngrok Blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"ngrok Blog","logo":"https://media.daily.dev/image/upload/s--718XXxvE--/f_auto,q_auto/v1787469610/logos/ngrok?_a=BAMAMicg0","url":"https://daily.dev/sources/ngrok"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"react,devtools,nodejs,authentication,oauth","timeRequired":"PT9M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"ngrok Blog","item":"https://daily.dev/sources/ngrok"},{"@type":"ListItem","position":3,"name":"Add OAuth 2.0 to a Node.js CRUD app"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/add-oauth-2-0-to-a-node-js-crud-app-bim8ybsom#faq","mainEntity":[{"@type":"Question","name":"How do I add Google OAuth authentication to my Node.js app using ngrok?","acceptedAnswer":{"@type":"Answer","text":"Add the .oauth(\"google\") method to the ngrok listener object, calling it after .domain() and before .listen(). This requires all incoming requests, including those to the React frontend and REST API, to authenticate with Google OAuth. You can restrict access further by passing allowed domains or specific email addresses as arguments to the oauth() function. See how daily.dev surfaces practical OAuth and ngrok integration walkthroughs for shipping secure Node.js apps."}},{"@type":"Question","name":"Why should I use the ngrok JavaScript SDK instead of the ngrok CLI agent for production apps?","acceptedAnswer":{"@type":"Answer","text":"The ngrok CLI agent assigns a random domain that changes every session, which works for local testing but breaks OAuth setups requiring a stable redirect URL. The ngrok JavaScript SDK lets you define ingress directly in code with a static domain, such as spin-vinyl-js.ngrok.io, so the domain stays consistent across restarts and environments. Developers weighing ingress tooling choices track comparisons like this on daily.dev before locking in an architecture."}}]}
```

