Enterprise-grade OAuth 2.1 authentication for your applications
// 1. Redirect users to Wenme OAuth authorization
const authUrl = new URL('https://identity.wenme.net/oauth/authorize');
authUrl.searchParams.append('client_id', 'YOUR_CLIENT_ID');
authUrl.searchParams.append('redirect_uri', 'YOUR_CALLBACK_URL');
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('scope', 'openid profile email');
authUrl.searchParams.append('state', generateRandomState());
// 2. PKCE (required for security)
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
authUrl.searchParams.append('code_challenge', codeChallenge);
authUrl.searchParams.append('code_challenge_method', 'S256');
window.location.href = authUrl.toString();
Go to Wenme Dashboard and create a new OAuth application.
Never expose your Client Secret in client-side code.
# .env file
WENME_CLIENT_ID=wenme_abc123...
WENME_CLIENT_SECRET=secret_xyz789...
WENME_REDIRECT_URI=https://yourapp.com/auth/callback
Redirect user to Wenme authorization endpoint with PKCE parameters.
// 1. Redirect users to Wenme OAuth authorization
const authUrl = new URL('https://identity.wenme.net/oauth/authorize');
authUrl.searchParams.append('client_id', 'YOUR_CLIENT_ID');
authUrl.searchParams.append('redirect_uri', 'YOUR_CALLBACK_URL');
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('scope', 'openid profile email');
authUrl.searchParams.append('state', generateRandomState());
// 2. PKCE (required for security)
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
authUrl.searchParams.append('code_challenge', codeChallenge);
authUrl.searchParams.append('code_challenge_method', 'S256');
window.location.href = authUrl.toString();
Exchange authorization code for access tokens.
// 3. Exchange authorization code for tokens
const response = await fetch('https://identity.wenme.net/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
grant_type: 'authorization_code',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
code: authorizationCode,
redirect_uri: 'YOUR_CALLBACK_URL',
code_verifier: codeVerifier // PKCE verifier
})
});
const tokens = await response.json();
// tokens.access_token, tokens.id_token, tokens.refresh_token
Use access token to fetch user profile.
// 4. Get user information
const userResponse = await fetch('https://identity.wenme.net/api/user/profile', {
headers: {
'Authorization': `Bearer ${tokens.access_token}`
}
});
const user = await userResponse.json();
// user.id, user.email, user.name, user.avatar
PKCE (Proof Key for Code Exchange) is required for all OAuth flows to prevent authorization code interception attacks. This is especially critical for mobile and single-page applications.
// Generate code verifier (43-128 characters)
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// Generate code challenge from verifier
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const hash = await crypto.subtle.digest('SHA-256', data);
return btoa(String.fromCharCode(...new Uint8Array(hash)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
// 1. Redirect users to Wenme OAuth authorization
const authUrl = new URL('https://identity.wenme.net/oauth/authorize');
authUrl.searchParams.append('client_id', 'YOUR_CLIENT_ID');
authUrl.searchParams.append('redirect_uri', 'YOUR_CALLBACK_URL');
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('scope', 'openid profile email');
authUrl.searchParams.append('state', generateRandomState());
// 2. PKCE (required for security)
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
authUrl.searchParams.append('code_challenge', codeChallenge);
authUrl.searchParams.append('code_challenge_method', 'S256');
window.location.href = authUrl.toString();
// 3. Exchange authorization code for tokens
const response = await fetch('https://identity.wenme.net/oauth/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
grant_type: 'authorization_code',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
code: authorizationCode,
redirect_uri: 'YOUR_CALLBACK_URL',
code_verifier: codeVerifier // PKCE verifier
})
});
const tokens = await response.json();
// tokens.access_token, tokens.id_token, tokens.refresh_token
// 4. Get user information
const userResponse = await fetch('https://identity.wenme.net/api/user/profile', {
headers: {
'Authorization': `Bearer ${tokens.access_token}`
}
});
const user = await userResponse.json();
// user.id, user.email, user.name, user.avatar
Endpoint | Method | Description |
---|---|---|
/oauth/authorize | GET | OAuth authorization endpoint |
/oauth/token | POST | Exchange code for tokens |
/api/user/profile | GET | Get user information |
/oauth/revoke | POST | Revoke access token |
/.well-known/openid-configuration | GET | OpenID Connect discovery |
/.well-known/jwks.json | GET | JSON Web Key Set |
Scope | Description |
---|---|
openid | OpenID Connect authentication |
profile | User profile information (name, avatar) |
User email address | |
offline_access | Refresh token for long-term access |
You can create a test application in the dashboard for development purposes.
Create Test AppUse our built-in OAuth flow tester to validate your configuration.
Our team is here to help you integrate Wenme authentication into your applications.