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

基于Django默认用户表实现WordPress与Django同域单点登录

同域下基于Django默认用户表实现与WordPress的自动会话同步(无需WP-API)

核心思路

因为是同域环境,我们可以在Django用户登录成功后,直接完成两个关键操作:

  1. 将Django用户同步到WordPress的用户表(不存在则创建)
  2. 生成符合WordPress规则的会话Cookie,让WordPress识别用户已登录

步骤1:配置跨库访问(Django连接WordPress数据库)

首先在Django的settings.py中添加WordPress数据库的配置(两者用同数据库可跳过此配置):

DATABASES = {
    'default': {
        # 你的Django数据库配置
    },
    'wp': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'wordpress_db_name',
        'USER': 'wp_db_user',
        'PASSWORD': 'wp_db_password',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

同时把WordPress的密钥配置到Django中(从WordPress的wp-config.php里复制AUTH_KEY和SECURE_AUTH_KEY):

WORDPRESS_AUTH_KEY = '你的WordPress AUTH_KEY'
WORDPRESS_SECURE_AUTH_KEY = '你的WordPress SECURE_AUTH_KEY'
DOMAIN = '.example.com'  # 同域根域名,比如主站是example.com,子域统一用这个

步骤2:同步Django用户到WordPress

在Django的登录视图中,处理用户登录成功后的同步逻辑。注意要兼容WordPress的密码哈希规则:

from django.contrib.auth import authenticate, login
from django.db import connections
from django.shortcuts import redirect, render
import hashlib
import random
import time
from django.conf import settings
from django.utils.http import http_date
import hmac

def wordpress_hash_password(password):
    # 模拟WordPress的PHPass哈希逻辑(兼容新旧版本WP)
    salt = hashlib.sha1(str(random.random()).encode()).hexdigest()[:8]
    hash_str = hashlib.md5((password + salt).encode()).hexdigest()
    return f'$P${salt}${hash_str}'

def custom_login(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            
            # 同步用户到WordPress数据库
            with connections['wp'].cursor() as cursor:
                # 检查用户是否已存在于WP表中
                cursor.execute("SELECT ID FROM wp_users WHERE user_login = %s", [user.username])
                wp_user_row = cursor.fetchone()
                
                if not wp_user_row:
                    # 创建WordPress用户
                    wp_hashed_pwd = wordpress_hash_password(password)
                    cursor.execute("""
                        INSERT INTO wp_users (user_login, user_pass, user_nicename, user_email, user_registered)
                        VALUES (%s, %s, %s, %s, NOW())
                    """, [user.username, wp_hashed_pwd, user.username, user.email])
                    wp_user_id = cursor.lastrowid
                    
                    # 同步基础用户元数据(可选)
                    cursor.execute("INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (%s, %s, %s)", 
                                  [wp_user_id, 'first_name', user.first_name])
                    cursor.execute("INSERT INTO wp_usermeta (user_id, meta_key, meta_value) VALUES (%s, %s, %s)", 
                                  [wp_user_id, 'last_name', user.last_name])
                else:
                    wp_user_id = wp_user_row[0]
            
            # 生成并设置WordPress会话Cookie
            response = set_wordpress_session_cookie(request, wp_user_id, user.username)
            return response
    # GET请求返回登录页面
    return render(request, 'login.html')

步骤3:生成WordPress会话Cookie

编写函数生成符合WordPress规则的登录Cookie,确保WordPress能识别用户身份:

def set_wordpress_session_cookie(request, wp_user_id, username):
    auth_key = settings.WORDPRESS_AUTH_KEY
    secure_auth_key = settings.WORDPRESS_SECURE_AUTH_KEY
    domain = settings.DOMAIN
    
    # 生成logged_in Cookie的哈希值
    cookie_hash = hmac.new(auth_key.encode(), f"{wp_user_id}|{username}".encode(), hashlib.sha256).hexdigest()
    expiration = int(time.time()) + 86400 * 14  # 两周有效期,和WP默认一致
    cookie_value = f"{wp_user_id}|{expiration}|{cookie_hash}|{username}"
    
    # 生成Cookie名称(WP会根据域名生成前缀)
    cookie_name_prefix = hmac.new(auth_key.encode(), domain.encode(), hashlib.md5).hexdigest()[:32]
    logged_in_cookie_name = f'wordpress_logged_in_{cookie_name_prefix}'
    
    # 设置基础登录Cookie
    response = redirect('/')
    response.set_cookie(
        logged_in_cookie_name,
        cookie_value,
        expires=http_date(expiration),
        domain=domain,
        path='/',
        secure=request.is_secure(),
        httponly=True,
        samesite='Lax'
    )
    
    # HTTPS环境下添加secure Cookie
    if request.is_secure():
        secure_cookie_prefix = hmac.new(secure_auth_key.encode(), domain.encode(), hashlib.md5).hexdigest()[:32]
        secure_cookie_name = f'wordpress_sec_{secure_cookie_prefix}'
        response.set_cookie(
            secure_cookie_name,
            cookie_value,
            expires=http_date(expiration),
            domain=domain,
            path='/',
            secure=True,
            httponly=True,
            samesite='Lax'
        )
    
    return response

步骤4:同步登出(可选)

在Django登出时,清除WordPress的会话Cookie,确保两边状态一致:

from django.contrib.auth import logout

def custom_logout(request):
    logout(request)
    response = redirect('/')
    domain = settings.DOMAIN
    auth_key = settings.WORDPRESS_AUTH_KEY
    secure_auth_key = settings.WORDPRESS_SECURE_AUTH_KEY
    
    # 清除logged_in Cookie
    cookie_prefix = hmac.new(auth_key.encode(), domain.encode(), hashlib.md5).hexdigest()[:32]
    response.delete_cookie(f'wordpress_logged_in_{cookie_prefix}', domain=domain, path='/')
    
    # 清除HTTPS环境下的secure Cookie
    if request.is_secure():
        secure_prefix = hmac.new(secure_auth_key.encode(), domain.encode(), hashlib.md5).hexdigest()[:32]
        response.delete_cookie(f'wordpress_sec_{secure_prefix}', domain=domain, path='/')
    
    return response

关键注意事项

  • 同域配置:WordPress的wp-config.php中必须设置define('COOKIE_DOMAIN', '.example.com');,Django的settings.py设置SESSION_COOKIE_DOMAIN = '.example.com'和CSRF_COOKIE_DOMAIN = '.example.com',确保Cookie跨子域共享。
  • 密码哈希兼容:如果你的WordPress使用PHP 5.5+的password_hash()(而非旧版PHPass),需要调整wordpress_hash_password函数,或者直接调用PHP脚本生成哈希(比如用subprocess执行简单的PHP脚本)。
  • 用户信息同步:如果Django用户修改了邮箱、密码等信息,需要通过Django的post_save信号同步到WordPress,避免两边数据不一致。

内容的提问来源于stack exchange,提问作者Aditya Prakash Gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 23:48:17