Authentication Flow
How the OAuth 2.1 Authorization Code Flow with PKCE works in NETWORKCOIN.ID.
Overview
Flow
1. User clicks "Sign in with NetworkCoin" in your app
2. Your app redirects to /oauth/authorize with PKCE challenge
3. User authenticates (email/password OR wallet signature)
4. User consents to share data (first time only — remembered after)
5. NETWORKCOIN.ID redirects back with ?code=xxx
6. Your app exchanges code for tokens via /oauth/token
7. Your app calls /oauth/userinfo to get the user profile
8. (Optional) Use refresh token to silently renew accessStep 1: Authorization Request
Redirect the user to the authorization endpoint with these parameters:
| Parameter | Required | Description |
|---|---|---|
| client_id | Yes | Your app's client ID |
| redirect_uri | Yes | Must match Console config |
| response_type | Yes | Always code |
| scope | Yes | Space-separated scopes |
| code_challenge | Yes | PKCE S256 challenge |
| code_challenge_method | Yes | Always S256 |
| state | Recommended | CSRF protection |
| nonce | Optional | Replay protection |
Generating PKCE Challenge
JavaScript
const verifier = crypto.randomUUID() + crypto.randomUUID();
const encoder = new TextEncoder();
const digest = await crypto.subtle.digest('SHA-256', encoder.encode(verifier));
const challenge = btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
// Store verifier in sessionStorage for step 3
sessionStorage.setItem('pkce_verifier', verifier);Step 2: User Authentication
The user lands on the NETWORKCOIN.ID login page with two options:
- Email tab: Enter email and password (or register)
- Wallet tab: Connect MetaMask, sign an EIP-4361 (SIWE) message
Step 3: Consent
First time only. The user sees which scopes your app requests and approves. Consent is remembered — on subsequent visits the user is redirected automatically.
Step 4: Token Exchange
POST /oauth/token
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&redirect_uri=https://yourapp.com/callback
&client_id=YOUR_CLIENT_ID
&code_verifier=STORED_PKCE_VERIFIERResponse:
Response
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 3600,
"id_token": "eyJ...",
"refresh_token": "dGhpcyBpcyBh...",
"scope": "openid profile email wallet"
}Step 5: Get User Info
GET /oauth/userinfo
Authorization: Bearer ACCESS_TOKEN
Response:
{
"sub": "550e8400-e29b-41d4-a716-446655440000",
"name": "Alice",
"email": "alice@example.com",
"email_verified": true,
"picture": "https://ui-avatars.com/api/?name=Alice",
"wallet_address": "0x742d35Cc6634C0532925a3b..."
}Token Refresh
When the access token expires (1 hour), use the refresh token. Tokens are rotated — each refresh returns a new refresh token and revokes the old one.
POST /oauth/token
grant_type=refresh_token
&refresh_token=REFRESH_TOKEN
&client_id=YOUR_CLIENT_IDLogout
GET /oauth/logout?client_id=YOUR_CLIENT_ID&post_logout_redirect_uri=https://yourapp.com