You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现Chrome扩展与Next.js Web应用的登录状态同步

Chrome扩展与Next Auth Web应用登录状态同步方案

已经拿到Web应用传来的access token后,扩展内的认证流程核心是持久化存储token、验证有效性、维护登录态、请求时携带token,具体步骤如下:

1. 持久化存储Access Token

把接收到的token和过期时间存储到Chrome扩展的本地存储中,确保页面刷新或扩展重启后能恢复状态:

// 在扩展的背景页/服务工作者中监听Web应用的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'SYNC_LOGIN_TOKEN') {
    // 存储token及过期时间(如果Next Auth返回了expires_in)
    chrome.storage.local.set({ 
      accessToken: message.accessToken,
      expiresAt: Date.now() + (message.expiresIn || 3600) * 1000, // 默认1小时过期
      refreshToken: message.refreshToken // 如果有refresh token也一起存
    }, () => {
      // 触发扩展内的登录状态更新逻辑
      updateAuthState(true);
    });
  }
});

2. 验证Token有效性(可选但推荐)

使用Next Auth的会话验证端点或服务商的token校验接口,确保存储的token未失效:

async function validateAccessToken(accessToken) {
  try {
    // 调用Next Auth的会话接口验证token
    const res = await fetch('/api/auth/session', {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    });
    return res.ok;
  } catch (err) {
    console.error('Token验证失败:', err);
    return false;
  }
}

3. 扩展内维护登录状态

在扩展的popup、content script等页面初始化时,读取存储的token并判断登录状态:

// popup页面初始化时检查登录状态
document.addEventListener('DOMContentLoaded', async () => {
  const { accessToken, expiresAt } = await chrome.storage.local.get(['accessToken', 'expiresAt']);
  
  if (accessToken && expiresAt > Date.now()) {
    const isValid = await validateAccessToken(accessToken);
    if (isValid) {
      // 渲染已登录UI
      renderLoggedInUI();
    } else {
      // token无效,清理存储
      chrome.storage.local.remove(['accessToken', 'expiresAt', 'refreshToken']);
      renderLoggedOutUI();
    }
  } else {
    renderLoggedOutUI();
  }
});

4. 处理Token过期与刷新

如果Next Auth返回了refresh token,实现自动刷新逻辑,避免用户重复登录:

async function refreshAuthToken() {
  const { refreshToken } = await chrome.storage.local.get('refreshToken');
  if (!refreshToken) return false;

  try {
    const res = await fetch('/api/auth/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        grant_type: 'refresh_token',
        refresh_token: refreshToken,
        client_id: 'your-next-auth-client-id' // 按需填写
      })
    });
    const data = await res.json();
    
    if (data.access_token) {
      await chrome.storage.local.set({
        accessToken: data.access_token,
        expiresAt: Date.now() + data.expires_in * 1000,
        refreshToken: data.refresh_token || refreshToken
      });
      return true;
    }
    return false;
  } catch (err) {
    console.error('Token刷新失败:', err);
    return false;
  }
}

5. 扩展内API请求携带Token

所有需要认证的接口请求,都在请求头中携带存储的access token:

async function fetchProtectedResource() {
  const { accessToken } = await chrome.storage.local.get('accessToken');
  if (!accessToken) throw new Error('用户未登录');

  const res = await fetch('https://your-api.com/protected-endpoint', {
    headers: { 'Authorization': `Bearer ${accessToken}` }
  });
  
  if (!res.ok) {
    // 若返回401,尝试刷新token后重试
    const refreshed = await refreshAuthToken();
    if (refreshed) return fetchProtectedResource();
    throw new Error('认证失败');
  }
  
  return res.json();
}

内容的提问来源于stack exchange,提问作者sid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:27:19