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

如何在Django中限制用户仅访问所属站点?

限制Django用户仅访问所属站点的实现方案

1. 扩展用户模型,关联站点

首先需要给用户模型添加与Django内置Site模型的关联,让每个用户归属到特定站点。通过继承AbstractUser扩展模型:

from django.contrib.auth.models import AbstractUser
from django.contrib.sites.models import Site
from django.db import models

class CustomUser(AbstractUser):
    # 关联用户所属的站点,外键支持用户归属单个站点
    site = models.ForeignKey(Site, on_delete=models.CASCADE, related_name='site_users')

之后在项目settings.py中配置自定义用户模型:

AUTH_USER_MODEL = 'your_app_name.CustomUser'

2. 自定义认证后端,拦截跨站点登录

编写自定义认证后端,在用户登录时验证其所属站点是否与当前访问的站点一致:

from django.contrib.auth.backends import ModelBackend
from django.contrib.sites.shortcuts import get_current_site
from .models import CustomUser

class SiteRestrictedAuthBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        # 无请求对象时直接返回None
        if not request:
            return None
        
        current_site = get_current_site(request)
        try:
            # 仅查找属于当前站点的用户
            user = CustomUser.objects.get(username=username, site=current_site)
            # 验证密码
            if user.check_password(password):
                return user
        except CustomUser.DoesNotExist:
            # 无匹配用户时返回None,保持默认登录失败提示
            return None

将自定义后端配置到settings.py:

AUTHENTICATION_BACKENDS = [
    'your_app_name.backends.SiteRestrictedAuthBackend',
]

3. 添加中间件,防止已登录用户跨站点访问

即使用户已登录,若尝试访问其他站点,需强制登出或拒绝访问。编写中间件:

from django.contrib.auth import logout
from django.contrib.sites.shortcuts import get_current_site
from django.http import HttpResponseForbidden

class SiteAccessControlMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if request.user.is_authenticated:
            current_site = get_current_site(request)
            # 检查用户所属站点是否与当前站点匹配
            if request.user.site != current_site:
                logout(request)
                return HttpResponseForbidden("您无权访问该站点")
        
        response = self.get_response(request)
        return response

在settings.py的MIDDLEWARE列表中添加该中间件,注意需放在django.contrib.auth.middleware.AuthenticationMiddleware之后:

MIDDLEWARE = [
    # ... 其他中间件
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'your_app_name.middleware.SiteAccessControlMiddleware',
    # ... 其他中间件
]

4. 注册用户时自动关联当前站点

在用户注册流程中,自动将当前访问的站点关联到新创建的用户:

from django.contrib.sites.shortcuts import get_current_site
from django.views.generic.edit import CreateView
from .forms import CustomUserCreationForm
from django.urls import reverse_lazy

class SignUpView(CreateView):
    form_class = CustomUserCreationForm
    template_name = 'auth/signup.html'
    success_url = reverse_lazy('login')

    def form_valid(self, form):
        current_site = get_current_site(self.request)
        user = form.save(commit=False)
        user.site = current_site
        user.save()
        return super().form_valid(form)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:07