LxBlog
/Docs

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_STATE

Query Parameters

NameTypeDescription
response_type*stringMust be "code" for the authorization code flow.
client_id*stringYour application's client ID, obtained when you registered your app.
redirect_uri*stringOne of the redirect URIs you registered for your app. Must be an exact match.
scope*stringA space-separated list of permissions your app is requesting (e.g. "articles:read blog:read").
state*stringA random, unguessable string used to protect against CSRF attacks. You must validate this when the user is redirected back.
code_challengestringRequired for PKCE. The base64url-encoded SHA-256 hash of the code_verifier.
code_challenge_methodstringMust 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.

  1. Generate a code_verifier: a cryptographically random string between 43 and 128 characters, using unreserved characters (A-Z, a-z, 0-9, -._~).
  2. Compute the code_challenge: base64url(sha256(code_verifier)).
  3. Include code_challenge and code_challenge_method=S256 in the authorization URL.
pkce.js
// 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_STATE
  • code — 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.