OAuth 2.0 Authentication in Chrome Extensions: Complete Guide (2026)
OAuth 2.0 for Chrome Extensions
OAuth 2.0 lets your extension access Google APIs (Gmail, Drive, Calendar, Contacts) on behalf of users — without handling passwords. Chrome’s Identity API (chrome.identity) simplifies the entire OAuth flow, managing tokens and consent screens automatically.
Architecture: Why Extensions Need Special Handling
Extensions can’t use the standard OAuth redirect flow because they don’t load over HTTPS. Chrome’s Identity API provides:
- Built-in consent screen management
- Automatic token caching and refresh
- No redirect URI configuration needed
- Silent authentication for returning users
Step 1: Get a Stable Extension ID
Your OAuth credentials are tied to your extension ID, so it must stay consistent:
- Upload your extension to the Chrome Developer Dashboard (no need to publish)
- Go to Package tab → Copy the public key
- Add it to manifest.json (single line, no newlines):
{
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
}- Verify your ID matches on
chrome://extensions
Step 2: Create OAuth Credentials
- Go to Google API Console
- Create or select a project
- Navigate to Credentials → Create Credentials → OAuth 2.0 Client ID
- Select Chrome Extension as application type
- Enter your extension ID
- Enable the APIs you need (e.g., People API, Gmail API, Drive API)
- Create an API key for the project
Step 3: Configure the Manifest
{
"manifest_version": 3,
"name": "My Google Integration",
"version": "1.0",
"permissions": ["identity", "storage"],
"oauth2": {
"client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"scopes": [
"https://www.googleapis.com/auth/contacts.readonly",
"https://www.googleapis.com/auth/userinfo.profile"
]
},
"action": {
"default_popup": "popup.html"
}
}Common OAuth Scopes
| Scope | Access |
|---|---|
userinfo.profile | Basic profile info |
userinfo.email | Email address |
contacts.readonly | Read contacts |
gmail.readonly | Read Gmail messages |
drive.readonly | Read Google Drive files |
calendar.readonly | Read calendar events |
spreadsheets.readonly | Read Google Sheets |
Step 4: Implement Authentication
Get an OAuth Token
async function getAuthToken(interactive = true) {
return new Promise((resolve, reject) => {
chrome.identity.getAuthToken({ interactive }, (token) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
return;
}
resolve(token);
});
});
}Make Authenticated API Calls
async function fetchUserProfile() {
const token = await getAuthToken();
const response = await fetch(
'https://www.googleapis.com/oauth2/v2/userinfo',
{
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json'
}
}
);
if (response.status === 401) {
// Token expired — remove and retry
await removeCachedToken(token);
return fetchUserProfile();
}
return response.json();
}
async function fetchContacts() {
const token = await getAuthToken();
const apiKey = 'YOUR_API_KEY';
const response = await fetch(
`https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses&key=${apiKey}`,
{
headers: { Authorization: `Bearer ${token}` }
}
);
return response.json();
}Token Management
async function removeCachedToken(token) {
return new Promise((resolve) => {
chrome.identity.removeCachedAuthToken({ token }, resolve);
});
}
async function signOut() {
const token = await getAuthToken(false);
if (token) {
// Revoke the token server-side
await fetch(`https://accounts.google.com/o/oauth2/revoke?token=${token}`);
await removeCachedToken(token);
}
}Complete Popup Example
// popup.js
document.getElementById('sign-in-btn').addEventListener('click', async () => {
try {
const token = await getAuthToken(true);
const profile = await fetchUserProfile();
document.getElementById('user-name').textContent = profile.name;
document.getElementById('user-email').textContent = profile.email;
document.getElementById('user-avatar').src = profile.picture;
document.getElementById('signed-out').style.display = 'none';
document.getElementById('signed-in').style.display = 'block';
} catch (error) {
document.getElementById('error').textContent = error.message;
}
});
document.getElementById('sign-out-btn').addEventListener('click', async () => {
await signOut();
document.getElementById('signed-out').style.display = 'block';
document.getElementById('signed-in').style.display = 'none';
});
// Auto-sign-in on popup open (non-interactive)
(async () => {
try {
const token = await getAuthToken(false);
if (token) {
const profile = await fetchUserProfile();
// Update UI...
}
} catch {
// Not signed in — show sign-in button
}
})();Common Pitfalls
- Mismatched extension IDs — Your unpacked ID must match the Dashboard ID. Always use the
keyfield. - Forgetting to enable APIs — Creating OAuth credentials isn’t enough. Enable each API in the Google Cloud Console.
- Scope changes after publish — Adding new scopes requires users to re-authorize. Plan your scopes upfront.
- Not handling token expiry — Tokens expire. Always handle 401 responses by clearing the cache and retrying.
- Interactive flag in service workers —
interactive: truerequires a user gesture context. Call from popup or options page.
What’s Next
OAuth 2.0 via Chrome’s Identity API gives your extension secure access to the entire Google ecosystem. Start with read-only scopes, handle token lifecycle properly, and always provide a clear sign-out option.
Grow your authenticated extension with ExtensionBooster’s developer tools.
Share this article
Build better extensions with free tools
Icon generator, MV3 converter, review exporter, and more — no signup needed.
Related Articles
I Built the Same Chrome Extension With 5 Different Frameworks. Here's What Actually Happened.
WXT vs Plasmo vs CRXJS vs Extension.js vs Bedframe. Real benchmarks, honest opinions, and the framework with 12K stars that's quietly dying.
5 Best Email Marketing Services to Grow Your Chrome Extension (2026)
Compare the top email marketing platforms for SaaS and Chrome extension developers. MailerLite, Mailchimp, Brevo, ActiveCampaign, and Drip reviewed.
15 Best Practices to Build a Browser Extension That Users Love (2026 Guide)
Master browser extension development in 2026. Manifest V3, security, performance, and UX best practices to build extensions users love.