Brainxiex OAuth2 Provider memungkinkan aplikasi pihak ketiga menggunakan akun Brainxiex untuk autentikasi user, mirip dengan Google Sign-In atau Facebook Login.
Standar OAuth2 untuk aplikasi web dengan keamanan maksimal
Keamanan tambahan untuk mobile apps dan Single Page Applications
Auto-renew access token tanpa user login ulang
User approval untuk setiap aplikasi yang mengakses data
| Endpoint | Description |
|---|---|
/oauth2/authorize |
Authorization endpoint untuk user login |
/api/oauth2/token |
Token endpoint untuk exchange code/token |
/api/oauth2/userinfo |
User info endpoint untuk mendapatkan data user |
Redirect user ke halaman authorization Brainxiex dengan parameter yang diperlukan.
const clientId = 'your_client_id';
const redirectUri = 'https://your-app.com/callback';
const scope = 'profile email';
const state = 'random_state_string';
// Optional: PKCE for additional security
const codeVerifier = generateRandomString(43);
const codeChallenge = base64UrlEncode(sha256(codeVerifier));
const authUrl = new URL('https://brainxiex.com/oauth2/authorize');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', clientId);
authUrl.searchParams.set('redirect_uri', redirectUri);
authUrl.searchParams.set('scope', scope);
authUrl.searchParams.set('state', state);
authUrl.searchParams.set('code_challenge', codeChallenge);
authUrl.searchParams.set('code_challenge_method', 'S256');
// Redirect user to authUrl
window.location.href = authUrl.toString();
User akan diarahkan ke halaman login Brainxiex dan melihat halaman consent yang menampilkan:
Setelah user menyetujui, exchange authorization code untuk access token.
const code = 'authorization_code_from_callback';
const codeVerifier = 'same_code_verifier_from_step_1';
const response = await fetch('https://brainxiex.com/api/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'authorization_code',
code: code,
client_id: clientId,
client_secret: clientSecret,
redirect_uri: redirectUri,
code_verifier: codeVerifier
})
});
const tokens = await response.json();
// {
// access_token: "bx_access_...",
// token_type: "Bearer",
// expires_in: 3600,
// refresh_token: "bx_refresh_...",
// scope: "profile email"
// }
Gunakan access token untuk mendapatkan informasi user.
const userInfo = await fetch('https://brainxiex.com/api/oauth2/userinfo', {
headers: {
'Authorization': `Bearer ${tokens.access_token}`
}
});
const user = await userInfo.json();
// {
// sub: "123",
// brainxiex_id: "user_brainxiex_id",
// name: "User Name",
// picture: "https://...",
// username: "username",
// email: "[email protected]",
// email_verified: true
// }
Gunakan refresh token untuk mendapatkan access token baru tanpa login ulang.
const refreshToken = tokens.refresh_token;
const response = await fetch('https://brainxiex.com/api/oauth2/token', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
grant_type: 'refresh_token',
refresh_token: refreshToken,
client_id: clientId,
client_secret: clientSecret
})
});
const newTokens = await response.json();
// New access_token and refresh_token
Exchange authorization code atau refresh token untuk access token.
https://brainxiex.com/api/oauth2/token
grant_type=authorization_code
&code=AUTHORIZATION_CODE
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&redirect_uri=REDIRECT_URI
&code_verifier=CODE_VERIFIER (optional, for PKCE)
{
"access_token": "bx_access_...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "bx_refresh_...",
"scope": "profile email"
}
Get user information menggunakan access token.
https://brainxiex.com/api/oauth2/userinfo
Authorization: Bearer ACCESS_TOKEN
{
"sub": "123",
"brainxiex_id": "user_brainxiex_id",
"name": "User Name",
"picture": "https://...",
"username": "username",
"email": "[email protected]",
"email_verified": true,
"phone_number": "628123456789",
"phone_number_verified": true
}
Scopes menentukan data apa yang bisa diakses oleh aplikasi Anda.
| Scope | Description | Data Returned |
|---|---|---|
| profile | Basic profile information | name, picture, username |
| Email address | email, email_verified | |
| WhatsApp number | phone_number, phone_number_verified |
profile email untuk data dasar + email, atau profile email whatsapp untuk semua data.
// Step 1: Generate PKCE (optional but recommended)
function generatePKCE() {
const codeVerifier = base64UrlEncode(crypto.getRandomValues(new Uint8Array(32)));
const codeChallenge = base64UrlEncode(await sha256(codeVerifier));
return { codeVerifier, codeChallenge };
}
// Step 2: Redirect to authorization
function login() {
const { codeVerifier, codeChallenge } = generatePKCE();
sessionStorage.setItem('code_verifier', codeVerifier);
const params = new URLSearchParams({
response_type: 'code',
client_id: 'your_client_id',
redirect_uri: 'https://your-app.com/callback',
scope: 'profile email',
state: generateRandomString(),
code_challenge: codeChallenge,
code_challenge_method: 'S256'
});
window.location.href = `https://brainxiex.com/oauth2/authorize?${params}`;
}
// Step 3: Handle callback
async function handleCallback() {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const codeVerifier = sessionStorage.getItem('code_verifier');
// Exchange code for token
const response = await fetch('https://brainxiex.com/api/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
client_id: 'your_client_id',
client_secret: 'your_client_secret',
redirect_uri: 'https://your-app.com/callback',
code_verifier: codeVerifier
})
});
const tokens = await response.json();
// Store tokens securely
localStorage.setItem('access_token', tokens.access_token);
localStorage.setItem('refresh_token', tokens.refresh_token);
// Get user info
const user = await getUserInfo(tokens.access_token);
console.log('Logged in as:', user);
}
const express = require('express');
const app = express();
app.get('/auth/login', (req, res) => {
const authUrl = new URL('https://brainxiex.com/oauth2/authorize');
authUrl.searchParams.set('response_type', 'code');
authUrl.searchParams.set('client_id', process.env.CLIENT_ID);
authUrl.searchParams.set('redirect_uri', process.env.REDIRECT_URI);
authUrl.searchParams.set('scope', 'profile email');
authUrl.searchParams.set('state', generateRandomString());
res.redirect(authUrl.toString());
});
app.get('/auth/callback', async (req, res) => {
const { code, state } = req.query;
// Exchange code for token
const tokenResponse = await fetch('https://brainxiex.com/api/oauth2/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
code,
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
redirect_uri: process.env.REDIRECT_URI
})
});
const tokens = await tokenResponse.json();
// Get user info
const userResponse = await fetch('https://brainxiex.com/api/oauth2/userinfo', {
headers: { 'Authorization': `Bearer ${tokens.access_token}` }
});
const user = await userResponse.json();
// Create or update user in your database
await upsertUser(user);
// Create session
req.session.user = user;
res.redirect('/dashboard');
});
Client ID atau Client Secret salah. Pastikan credentials benar dari dashboard.
Redirect URI tidak terdaftar. Pastikan redirect URI cocok persis dengan yang didaftarkan. Cek trailing slash.
Scope yang diminta tidak diizinkan. Pastikan scope sesuai dengan yang didaftarkan.
User menolak authorization. Tampilkan pesan yang user-friendly.