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

基于Manifest V3与Django 4的Chrome扩展-Django站点联动认证咨询

基于Django 4 + Chrome Manifest V3的联动认证方案(无DRF)

一、Cookie读取方案的合理性

读取Django的Session Cookie是可行且贴合场景的方案,无需额外引入DRF,可直接复用现有Django认证体系,只要严格遵循Manifest V3权限规则和Django的Cookie配置要求,就能安全适配Stripe支付管理场景。

关键配置前提

  1. 扩展权限配置:在manifest.json中添加必要权限:
{
  "permissions": ["cookies"],
  "host_permissions": ["https://your-django-site.com/*"],
  "content_scripts": [
    {
      "matches": ["https://your-django-site.com/*"],
      "js": ["content-script.js"]
    }
  ],
  "background": {
    "service_worker": "service-worker.js"
  }
}
  1. Django Cookie调整:在settings.py中确保Session Cookie适配扩展环境:
SESSION_COOKIE_SAMESITE = "Lax"  # 跨域场景设为"None",需配合SESSION_COOKIE_SECURE=True
SESSION_COOKIE_SECURE = True  # HTTPS环境强制开启
SESSION_COOKIE_HTTPONLY = True  # 安全起见保持开启,此时仅Service Worker可读取Cookie

二、登录状态自动同步实现

1. 站点登录成功后触发同步

在Django登录成功的模板/视图中,通过window.postMessage通知Content Script:

// Django登录成功页面的脚本
window.postMessage(
  { type: "DJANGO_LOGIN_SUCCESS" },
  "https://your-django-site.com" // 限定目标域名,避免恶意监听
);

2. 扩展侧接收并验证状态

Content Script监听站点消息

// content-script.js
window.addEventListener("message", (event) => {
  if (event.origin !== "https://your-django-site.com") return; // 校验来源域名
  if (event.data.type === "DJANGO_LOGIN_SUCCESS") {
    // 委托Service Worker获取并验证登录状态
    chrome.runtime.sendMessage({ action: "CHECK_LOGIN" }, (response) => {
      if (response.isLoggedIn) {
        // 更新扩展UI(如显示用户名、初始化Stripe相关操作)
        console.log("同步登录状态成功:", response.user);
      }
    });
  }
});

Service Worker获取Cookie并验证

// service-worker.js
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.action !== "CHECK_LOGIN") return;

  // 获取Django Session Cookie
  chrome.cookies.get(
    { url: "https://your-django-site.com", name: "sessionid" },
    (cookie) => {
      if (!cookie) {
        sendResponse({ isLoggedIn: false });
        return;
      }

      // 调用Django验证接口(无需DRF,普通视图即可)
      fetch("https://your-django-site.com/check-login/", {
        method: "GET",
        credentials: "include", // 自动携带Session Cookie
      })
        .then((res) => res.json())
        .then((data) => {
          sendResponse({
            isLoggedIn: data.is_logged_in,
            user: data.user, // 包含Stripe客户ID等必要信息
          });
        })
        .catch(() => sendResponse({ isLoggedIn: false }));
    }
  );
  return true; // 标记异步响应
});

Django验证视图(无DRF)

# views.py
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required

def check_login_status(request):
    if request.user.is_authenticated:
        return JsonResponse({
            "is_logged_in": True,
            "user": {
                "username": request.user.username,
                "stripe_customer_id": request.user.profile.stripe_customer_id  # 假设已关联Stripe客户
            }
        })
    return JsonResponse({"is_logged_in": False})

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path("check-login/", views.check_login_status, name="check_login"),
]

三、解决Service Worker与Content Script通信问题

常见问题是Service Worker主动发消息时找不到目标Tab,正确做法是通过标签页查询定位:

Service Worker主动推送状态变化

// service-worker.js
// 监听Cookie变化(如登出时Session Cookie过期)
chrome.cookies.onChanged.addListener((changeInfo) => {
  if (changeInfo.cookie.name !== "sessionid" || !changeInfo.cookie.url.includes("your-django-site.com")) return;

  // 查询站点的活跃Tab
  chrome.tabs.query({ url: "https://your-django-site.com/*" }, (tabs) => {
    tabs.forEach((tab) => {
      chrome.tabs.sendMessage(tab.id, {
        type: "LOGIN_STATUS_UPDATED",
        isLoggedIn: changeInfo.status !== "expired",
      });
    });
  });
});

Content Script监听Service Worker消息

// content-script.js
chrome.runtime.onMessage.addListener((msg) => {
  if (msg.type === "LOGIN_STATUS_UPDATED") {
    // 处理状态变化(如登出时重置扩展支付功能)
    console.log("登录状态更新:", msg.isLoggedIn);
  }
});

四、Stripe支付管理适配

  1. 扩展拿到stripe_customer_id后,可在Service Worker中调用Stripe API(需在manifest.json中添加Stripe API域名的host_permissions):
// service-worker.js
// 示例:创建Stripe支付Intent(生产环境建议通过Django代理,避免密钥暴露)
async function createPaymentIntent(customerId, amount) {
  const response = await fetch("https://api.stripe.com/v1/payment_intents", {
    method: "POST",
    headers: {
      "Authorization": "Bearer YOUR_STRIPE_SECRET_KEY",
      "Content-Type": "application/x-www-form-urlencoded",
    },
    body: new URLSearchParams({
      customer: customerId,
      amount: amount,
      currency: "usd",
    }),
  });
  return response.json();
}
  1. 生产环境禁止在扩展中存储Stripe密钥,建议通过Django后端代理Stripe请求,扩展调用Django接口间接操作。

五、安全与测试提示

  • 严格校验postMessage的origin,防止恶意站点触发扩展逻辑;
  • 始终使用HTTPS,确保Cookie的Secure属性生效;
  • 测试时通过Chrome DevTools查看Service Worker日志(Application -> Service Workers)和Content Script日志(页面DevTools -> Console)。

内容的提问来源于stack exchange,提问作者Fady's Cube

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 01:32:55