Chrome 插件登录流程技术设计文档

创建:xiaozi · 最后修改:xiaozi 2025-06-02 09:11 ·

一、概述

本技术设计文档详细描述了基于Chrome浏览器扩展的登录认证流程,旨在实现用户通过点击扩展图标触发登录操作,并完成认证后保存访问令牌(access_token)以便后续功能使用。设计基于标准的OAuth 2.0认证流程,利用Chrome扩展的background脚本和content脚本实现用户认证及令牌管理。

二、功能需求

  • 用户点击Chrome扩展图标,触发登录认证流程。
  • 检查是否存在有效的access_token,若不存在则记录postAuthSave并引导用户登录。
  • 打开认证服务提供的登录页面(AUTH_URL),完成用户认证。
  • 获取登录成功页面中的认证信息(cookie或令牌),并传递给background脚本。
  • 保存access_token,调用save(postAuthSave),并关闭登录成功的页面。
  • save方法调用过程中,向content_script.js发送状态消息(开始、成功、失败)。
  • 确保流程安全、高效,支持错误处理和用户体验优化。

三、技术架构

3.1 系统组件

  • popup.js: 处理用户点击扩展图标的交互逻辑,调用background脚本中的方法。
  • background.js: 核心逻辑脚本,负责检查和保存access_token,记录postAuthSave,调用save(postAuthSave),向content_script.js发送状态消息,以及控制登录页面的打开和关闭。
  • content_script.js: 注入到登录成功页面,提取认证信息(如cookie或令牌),接收并处理来自background.js的状态消息。
  • manifest.json: Chrome扩展的配置文件,定义权限、脚本注入规则等。
  • AUTH_URL: 认证服务提供的登录页面地址,用于用户认证。
  • chrome.storage: 用于存储access_tokenpostAuthSave,支持持久化保存。

3.2 技术选型

  • 语言: JavaScript
  • 存储: Chrome扩展的chrome.storage.local(本地存储,支持异步操作)
  • 通信: Chrome扩展的chrome.runtime消息传递机制
  • 认证协议: OAuth 2.0
  • 权限需求:
    • tabs: 用于打开和关闭登录页面
    • storage: 用于保存access_tokenpostAuthSave
    • cookies: 用于从登录成功页面提取认证信息
    • webNavigation(可选): 用于监听页面导航事件

四、详细设计

4.1 流程图

sequenceDiagram
    participant User as 用户
    participant Popup as popup.js
    participant Background as background.js
    participant Content as content_script.js
    participant AuthServer as 认证服务

    User->>Popup: 点击扩展图标
    Popup->>Background: 调用 save 方法
    Background->>Content: 发送“开始”消息
    Background->>Background: 检查 access_token
    alt access_token 不存在
        Background->>Background: 记录 postAuthSave
        Background->>User: chrome.tabs.create({ url: AUTH_URL })
        User->>AuthServer: 完成登录认证
        AuthServer->>Content: 加载登录成功页面
        Content->>Background: 发送 cookie 或 access_token
        Background->>Background: 保存 access_token
        Background->>Background: 调用 save(postAuthSave)
        alt save 成功
            Background->>Content: 发送“成功”消息
        else save 失败
            Background->>Content: 发送“失败”消息
        end
        Background->>User: 关闭登录成功页面
    else access_token 存在
        Background->>Content: 发送“成功”消息
        Background->>Popup: 返回已登录状态
    end

4.2 详细步骤

4.2.1 用户点击扩展图标

  • 用户点击Chrome扩展图标,触发popup.js中的逻辑。
  • popup.js通过chrome.runtime.sendMessage调用background.js中的save方法。

4.2.2 检查 access_token

  • background.js中的save方法通过chrome.storage.local.get检查是否已保存access_token
  • 在调用save方法时,向content_script.js发送“开始”消息(action: 'save_status', status: 'start')。
  • access_token存在且有效(可通过过期时间或验证接口判断),向content_script.js发送“成功”消息,返回已登录状态。
  • access_token不存在或无效,记录postAuthSave(通过chrome.storage.local.set保存),然后进入登录流程。

4.2.3 打开登录页面

  • 使用chrome.tabs.create({ url: AUTH_URL })打开认证服务的登录页面。
  • AUTH_URL为外部认证服务提供的OAuth 2.0登录入口(例如:https://auth.example.com/login)。
  • 登录页面需要支持重定向,成功登录后跳转到指定页面(包含认证信息)。

4.2.4 获取认证信息

  • 配置manifest.json中的content_scripts,确保content_script.js注入到登录成功页面(匹配URL模式,如https://auth.example.com/success*)。
  • content_script.js通过document.cookie或页面DOM提取access_token(或相关cookie)。
  • 使用chrome.runtime.sendMessage将提取的认证信息发送给background.js

4.2.5 保存 access_token 并执行后续操作

  • background.js接收到认证信息后,使用chrome.storage.local.set保存access_token
  • chrome.storage.local.get获取postAuthSave,调用save(postAuthSave)执行后续逻辑。
  • save(postAuthSave)执行成功,向content_script.js发送“成功”消息(action: 'save_status', status: 'success')。
  • save(postAuthSave)执行失败,向content_script.js发送“失败”消息(action: 'save_status', status: 'error')。
  • 通过chrome.tabs.remove关闭登录成功页面,优化用户体验。
  • 可选:通过chrome.runtime.sendMessage通知popup.js更新UI,显示登录成功状态。

五、代码实现

5.1 manifest.json

{
  "manifest_version": 3,
  "name": "认证扩展",
  "version": "1.0",
  "permissions": [
    "storage",
    "tabs",
    "cookies",
    "webNavigation"
  ],
  "background": {
    "service_worker": "background.js"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "content_scripts": [
    {
      "matches": ["https://auth.example.com/success*"],
      "js": ["content_script.js"]
    }
  ],
  "host_permissions": [
    "https://auth.example.com/*"
  ]
}

5.2 popup.js

document.addEventListener('DOMContentLoaded', () => {
  const loginButton = document.getElementById('loginButton');
  loginButton.addEventListener('click', () => {
    chrome.runtime.sendMessage({ action: 'save', postAuthSave: 'some_post_auth_action' }, (response) => {
      if (response.status === 'logged_in') {
        alert('已登录!');
      }
    });
  });
});

5.3 background.js

const AUTH_URL = 'https://auth.example.com/login';

function save(postAuthSave) {
  // 示例 save 方法,可根据实际需求实现
  try {
    console.log('Executing save with:', postAuthSave);
    // 实际实现可能涉及存储或其他操作
    return true; // 假设成功
  } catch (error) {
    console.error('Save failed:', error);
    return false;
  }
}

function sendStatusToContentScript(tabId, status) {
  chrome.tabs.sendMessage(tabId, { action: 'save_status', status: status }, (response) => {
    if (chrome.runtime.lastError) {
      console.error('Failed to send status to content script:', chrome.runtime.lastError);
    }
  });
}

chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'save') {
    // 发送“开始”消息
    if (sender.tab && sender.tab.id) {
      sendStatusToContentScript(sender.tab.id, 'start');
    }
    chrome.storage.local.get(['access_token'], (result) => {
      if (result.access_token) {
        // 发送“成功”消息
        if (sender.tab && sender.tab.id) {
          sendStatusToContentScript(sender.tab.id, 'success');
        }
        sendResponse({ status: 'logged_in' });
      } else {
        // 记录 postAuthSave
        chrome.storage.local.set({ postAuthSave: request.postAuthSave }, () => {
          chrome.tabs.create({ url: AUTH_URL });
        });
      }
    });
    return true; // 异步响应
  } else if (request.action === 'save_token') {
    chrome.storage.local.set({ access_token: request.token }, () => {
      // 获取 postAuthSave 并调用 save 方法
      chrome.storage.local.get(['postAuthSave'], (result) => {
        const saveSuccess = result.postAuthSave ? save(result.postAuthSave) : true;
        // 发送状态消息
        if (sender.tab && sender.tab.id) {
          sendStatusToContentScript(sender.tab.id, saveSuccess ? 'success' : 'error');
        }
        if (result.postAuthSave) {
          // 可选:清除 postAuthSave
          chrome.storage.local.remove('postAuthSave');
        }
        if (sender.tab && sender.tab.id) {
          chrome.tabs.remove(sender.tab.id);
        }
        sendResponse({ status: 'token_saved' });
      });
    });
    return true;
  }
});

5.4 content_script.js

document.addEventListener('DOMContentLoaded', () => {
  // 监听来自 background.js 的状态消息
  chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === 'save_status') {
      console.log('Received save status:', message.status);
      // 可根据状态更新 UI 或执行其他操作
      if (message.status === 'start') {
        console.log('Save process started');
      } else if (message.status === 'success') {
        console.log('Save process succeeded');
      } else if (message.status === 'error') {
        console.log('Save process failed');
      }
    }
  });

  // 提取 access_token
  const token = document.cookie
    .split('; ')
    .find(row => row.startsWith('access_token='))
    ?.split('=')[1];

  if (token) {
    chrome.runtime.sendMessage({
      action: 'save_token',
      token: token
    }, (response) => {
      if (response.status === 'token_saved') {
        console.log('Token saved successfully');
      }
    });
  }
});

5.5 popup.html

<!DOCTYPE html>
<html>
<head>
  <title>认证扩展</title>
</head>
<body>
  <button id="loginButton">登录</button>
  <script src="popup.js"></script>
</body>
</html>

六、安全考虑

  • 令牌存储: 使用chrome.storage.local存储access_tokenpostAuthSave,避免明文存储敏感信息,必要时可加密。
  • 权限控制: manifest.json中仅声明必要权限(如storagetabscookies),避免过度授权。
  • URL匹配: content_scriptsmatches字段严格限制为认证服务的成功页面,防止脚本注入无关页面。
  • HTTPS: 确保AUTH_URL和相关页面使用HTTPS,防止中间人攻击。
  • 令牌验证: 可选添加验证access_token有效性的逻辑(如通过API检查)。

七、错误处理

  • 登录失败: 若content_script.js无法提取access_token,通过chrome.runtime.sendMessage通知background.js,并提示用户重试。
  • 网络错误: 使用chrome.runtime.lastError检查chrome.tabs.createchrome.storage操作的错误。
  • 页面关闭失败: 若chrome.tabs.remove失败,记录日志但不影响主要功能。
  • 令牌过期: 在background.js中检查access_token的过期时间,必要时重新触发登录流程。
  • postAuthSave 失败: 若save(postAuthSave)执行失败,向content_script.js发送“失败”消息,记录错误日志。
  • 消息发送失败: 若chrome.tabs.sendMessage失败(例如content脚本未加载),通过chrome.runtime.lastError记录错误。

八、用户体验优化

  • 加载提示: 在popup.html中显示“正在登录...”提示,防止用户重复点击。
  • 成功反馈: 登录成功后,通过popup.js更新UI,显示“已登录”状态。
  • 自动关闭: 登录成功后自动关闭认证页面,避免用户手动操作。
  • 错误提示: 若登录失败或save(postAuthSave)失败,通过alert或自定义UI显示友好错误信息。
  • 状态反馈: content_script.js可根据收到的状态消息(开始、成功、失败)更新页面UI或记录日志。

九、测试计划

9.1 单元测试

  • 测试background.js中的save方法,验证access_token检查逻辑、postAuthSave保存/调用逻辑及状态消息发送。
  • 测试content_script.js中的cookie提取逻辑和状态消息接收逻辑,模拟不同cookie格式和消息状态。
  • 测试popup.js中的消息发送和响应处理。

9.2 集成测试

  • 模拟完整登录流程,验证从点击图标到保存access_token、调用save(postAuthSave)及发送状态消息的端到端功能。
  • 测试无网络情况下chrome.tabs.create的行为。
  • 测试登录失败场景(如无效cookie或页面加载失败)。
  • 测试postAuthSave的保存和调用逻辑,确保正确执行。
  • 测试状态消息的发送和接收,确保content_script.js正确处理“开始”、“成功”和“失败”消息。

9.3 安全测试

  • 验证content_scripts仅在指定URL运行。
  • 测试access_tokenpostAuthSave存储是否安全,尝试非法访问存储。
  • 测试状态消息的安全性,确保消息仅发送到正确的content脚本。

浏览 1442 次 · 下载PDF

首页 - Wiki
Copyright © 2011-2025 iteam. Current version is 2.144.1. UTC+08:00, 2025-07-19 09:26
浙ICP备14020137号-1 $访客地图$