The demo runs two Node.js servers entirely on your machine — no Google, no GitHub, no third-party involved.
localhost:3000 localhost:4000
(demo-app.js) (my-oauth-server.js)
using scg-auth YOUR OAuth 2.0 server
Open two terminals:
# Terminal 1 — start YOUR OAuth server
cd scg-auth
node examples/my-oauth-server.js
# Terminal 2 — start the demo app (uses scg-auth)
cd scg-auth
node examples/demo-app.js
Then open http://localhost:3000.
demo-app.js calls client.generateAuthUrl({ pkce: true }).
scg-auth automatically:
state (CSRF protection)code_verifier (PKCE)code_challenge = SHA-256(code_verifier) — Base64url encodedhttp://localhost:4000/authorize?client_id=...&state=...&code_challenge=...Your browser is redirected to that URL.
my-oauth-server.js receives the request, stores the OAuth params (state, PKCE challenge, scopes) in memory, and shows an email input form.
The server looks up your email in its user list, generates a 6-digit one-time code, and shows it directly on the page in a large green box.
!!! info “In a real deployment” Replace the on-screen display with an email/SMS send. The rest of the flow is identical.
The server:
http://localhost:3000/callback?code=XYZ&state=ABCdemo-app.js calls client.exchangeCode(code, { state }).
scg-auth automatically:
/token with code, client_id, redirect_uri, and code_verifiermy-oauth-server.js:
code_verifier against the stored code_challenge (PKCE check)access_token + refresh_tokendemo-app.js calls GET /me with the Bearer token. Your server returns the user profile. The page shows:
{
"name": "Harry Thapa",
"email": "hemantthapa1998@gmail.com",
"phone": "+447752106224",
"sub": "usr_harry_001",
"scope": "openid email profile"
}
The only config that makes it point at YOUR server:
const client = new SCGAuth({
authorizationUrl: "http://localhost:4000/authorize", // your server
tokenUrl: "http://localhost:4000/token", // your server
// ...
});
Change those two URLs to any OAuth 2.0 provider and the library works identically.