Quick Start
2. Authorization Flow
Authorization Flow
LxBlog uses the OAuth 2.0 Authorization Code flow. Your application redirects the user to LxBlog, where they grant permission, and then LxBlog redirects them back to your app with an authorization code.
Construct the Authorization URL
Redirect the user to the following URL to begin the authorization process:
https://lxblog.app/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=YOUR_REDIRECT_URI&scope=articles:read blog:read&state=RANDOM_STATEQuery Parameters
| Name | Type | Description |
|---|---|---|
response_type* | string | Must be "code" for the authorization code flow. |
client_id* | string | Your application's client ID, obtained when you registered your app. |
redirect_uri* | string | One of the redirect URIs you registered for your app. Must be an exact match. |
scope* | string | A space-separated list of permissions your app is requesting (e.g. "articles:read blog:read"). |
state* | string | A random, unguessable string used to protect against CSRF attacks. You must validate this when the user is redirected back. |
code_challenge | string | Required for PKCE. The base64url-encoded SHA-256 hash of the code_verifier. |
code_challenge_method | string | Must be "S256" when using PKCE. |
PKCE (for Public Clients)
If your application is a single-page app (SPA) or any other public client that cannot securely store a client secret, you should use Proof Key for Code Exchange (PKCE). This adds an extra layer of security to the authorization flow.
- Generate a code_verifier: a cryptographically random string between 43 and 128 characters, using unreserved characters (
A-Z,a-z,0-9,-._~). - Compute the code_challenge:
base64url(sha256(code_verifier)). - Include
code_challengeandcode_challenge_method=S256in the authorization URL.
// Generate a PKCE code verifier and challenge
function generateCodeVerifier() {
const array = new Uint8Array(32);
crypto.getRandomValues(array);
return base64UrlEncode(array);
}
function base64UrlEncode(buffer) {
return btoa(String.fromCharCode(...new Uint8Array(buffer)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}
async function generateCodeChallenge(verifier) {
const encoder = new TextEncoder();
const data = encoder.encode(verifier);
const digest = await crypto.subtle.digest('SHA-256', data);
return base64UrlEncode(digest);
}
// Usage
const codeVerifier = generateCodeVerifier();
const codeChallenge = await generateCodeChallenge(codeVerifier);
// Store codeVerifier securely — you will need it when exchanging the code for a token
console.log('Code Verifier:', codeVerifier);
console.log('Code Challenge:', codeChallenge);What Happens Next
When the user visits the authorization URL, they will see a consent screen where they can review the permissions your app is requesting. They will select which blog to grant access to and click "Authorize".
After authorizing, LxBlog redirects the user back to your redirect_uri with two query parameters:
https://yourapp.com/api/callback?code=AUTH_CODE&state=YOUR_STATEcode— a short-lived authorization code that you will exchange for an access token in the next step.state— the same value you sent in the authorization request.
Always validate the state parameter. Compare the returned value against the one you stored before initiating the authorization request. If they do not match, reject the request — it may be a CSRF attack.