User Authentication
Understand the complete login flow from the user's perspective, from clicking "Sign in with rNet" to landing back in your application.
Login Flow Overview
rNet OAuth uses an OAuth2 Authorization Code flow with PKCE (Proof Key for Code Exchange). This is the industry-standard approach for securely authenticating users in web applications without exposing secrets to the browser.
The state value is a random string created for each login attempt. Store it on your backend with the PKCE verifier. rNet returns the same state to your callback, so your app can find the correct verifier, connect the callback to the right user session, and reduce CSRF risk.
The examples below use an in-memory Map for clarity. In production, store this data in the user's server-side session, Redis, or another short-lived backend store.
1
User Clicks 'Sign in with rNet'
Your application displays a login button. When clicked, your backend generates a PKCE verifier and challenge, stores the verifier server-side, and redirects the user's browser to the rNet authorization page.
2
User Logs In or Creates an Account
The user is presented with the rNet login page. They can sign in with existing credentials or create a new rNet account. This happens entirely on the rNet domain so your app never sees the user's password.
3
User Grants Permission
After authentication, rNet shows the user which application is requesting access. The user approves, and rNet generates a one-time authorization code.
4
App Receives Authorization Code
rNet redirects the user's browser back to your registered Redirect URI with an authorization code appended as a query parameter. Your backend receives this code.
5
Backend Exchanges Code for Token
Your backend sends the authorization code along with the PKCE verifier to rNet's token endpoint. rNet validates everything and returns an access token and refresh token.
6
User is Redirected to Your App
Your backend stores the tokens in a secure session and redirects the user to your app's main page. The user is now authenticated and ready to use AI features.
Code Example
import crypto from 'node:crypto';
import { RNetAuth } from '@rnet-ai/rnet-oauth-node';
const auth = new RNetAuth({
clientId: process.env.RNET_CLIENT_ID,
clientSecret: process.env.RNET_CLIENT_SECRET,
redirectUri: 'https://myapp.com/callback'
});
// Demo store. Use a server-side session or Redis in production.
const stateStore = new Map();
// Step 1: Initiate login
app.get('/login', (req, res) => {
const { verifier, challenge } = auth.generatePKCE();
const state = crypto.randomBytes(16).toString('hex');
stateStore.set(state, {
verifier,
returnTo: '/dashboard'
});
setTimeout(() => stateStore.delete(state), 5 * 60 * 1000);
res.redirect(auth.getAuthorizationUrl(challenge, state));
});
// Step 5: Exchange code for tokens
app.get('/callback', async (req, res) => {
const { code, state, error, error_description } = req.query;
if (error) {
return res.status(400).send('Authentication failed: ' + error + ' - ' + (error_description || ''));
}
const stored = stateStore.get(state);
if (!code || !stored) {
return res.status(400).send('Invalid or expired login state. Please try again.');
}
const tokens = await auth.exchangeCodeForToken(code, stored.verifier);
stateStore.delete(state);
req.session.rnet = {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token
};
res.redirect(stored.returnTo);
});OAuth Login Across Apps
Once a user has authenticated with rNet, their login session can work across multiple connected applications. The user doesn't need to re-enter credentials for each app. rNet recognizes their active session and issues a new authorization code for each app that requests it.
The user's AI credit balance is checked during each AI request, regardless of which app they're using. All apps draw from the same centralized balance.
Security Note
The PKCE verifier and client secret must remain on the backend at all times. Never expose them in browser code, mobile bundles, or public repositories. Browser-only apps should call their own backend to start and complete the login flow.
Token-Based Access & Control
When an rNet access token is generated, it allows the developer to access all supported models through the rNet proxy. Your application can use that access token to make authenticated requests to any supported AI model route.
Credit deduction occurs automatically from the user's centralized wallet balance for every successful model request associated with that user's access token.
Supported AI Models
rNet currently works as a proxy. Copy the exact model name from the Supported Models page before sending a request.
text-embedding-3-small (OpenAI)gemini-2.5-flash-lite (Google)
Protecting Your Routes
Your backend should always verify that a valid rNet session exists before making AI requests. If the session is missing or the token is expired, return a 401 and prompt the user to log in again.
// Middleware to protect AI routes
function requireRNetSession(req, res, next) {
if (!req.session.rnet?.accessToken) {
return res.status(401).json({
error: 'Authentication required. Please sign in with rNet.'
});
}
next();
}
// Use on AI routes
app.post('/api/ai', requireRNetSession, async (req, res) => {
const response = await ai.chat(
req.body,
req.session.rnet.accessToken,
'gemini-2.5-flash-lite'
);
res.json(response);
});Important
The rNet SDKs do not provide built-in route guards or middleware. It is your application's responsibility to check for a valid session before making authenticated AI calls. Always treat the access token as a credential.