Django,使用多个域名的SESSION_COOKIE_DOMAIN

33
在Django中,我将SESSION_COOKIE_DOMAIN设置为我的域名。但实际上我想使用两个不同的域名运行相同的网站。
如果设置了SESSION_COOKIE_DOMAIN,则只有指定的域名允许用户登录。是否可以允许两个域名都能登录?
4个回答

45

如果您将会话cookie域设置为以“.”字符开头,它会允许您处理通配符子域并在多个子域之间共享会话cookie(登录会话)。

在settings.py中:
SESSION_COOKIE_DOMAIN=".stackoverflow.com"

以上配置允许cookie跨用户1.stackoverflow.com和user2.stackoverflow.com共享。

如果您确实希望对于相同的站点使用不同的url,您是否希望同一个用户在一个登录会话中在这两个站点之间切换?或者您只想要能够让两个不同的用户从两个不同的url(不是子域)登录到该网站吗?


我想要第二个。不是子域。基本上,我的客户有一个非常长的域名no-onewantstotype.net和quickname.net,这两个域名都需要正常工作。 - interstar
7
是否考虑将 longname.net 重定向到 shortname.net,以便所有用户只使用 shortname.net - Burhan Khalid
也可以在 example.comwww.example.com 之间工作。 - Hassan Baig
您不应该让一个 Web 应用程序从多个 URL 访问。您可以选择 "www.example.com" 或 "example.com" 中的一个,并将一个名称重定向所有请求到另一个。 - emyller

9

标准的SessionMiddleware只支持一个SESSION_COOKIE_DOMAIN,这仅适用于一个域及其子域。

这是一种变化,它将根据请求主机动态设置cookie域。要使用它,只需更新您的MIDDLEWARE_CLASSES以使用此SessionHostDomainMiddleware,而不是SessionMiddleware。这更好,@jcdyer和@interstar?

import time

from django.conf import settings
from django.utils.cache import patch_vary_headers
from django.utils.http import cookie_date
from django.contrib.sessions.middleware import SessionMiddleware

class SessionHostDomainMiddleware(SessionMiddleware):
    def process_response(self, request, response):
        """
        If request.session was modified, or if the configuration is to save the
        session every time, save the changes and set a session cookie.
        """
        try:
            accessed = request.session.accessed
            modified = request.session.modified
        except AttributeError:
            pass
        else:
            if accessed:
                patch_vary_headers(response, ('Cookie',))
            if modified or settings.SESSION_SAVE_EVERY_REQUEST:
                if request.session.get_expire_at_browser_close():
                    max_age = None
                    expires = None
                else:
                    max_age = request.session.get_expiry_age()
                    expires_time = time.time() + max_age
                    expires = cookie_date(expires_time)
                # Save the session data and refresh the client cookie.
                # Skip session save for 500 responses, refs #3881.
                if response.status_code != 500:
                    request.session.save()
                    host = request.get_host().split(':')[0]
                    response.set_cookie(settings.SESSION_COOKIE_NAME,
                            request.session.session_key, max_age=max_age,
                            expires=expires, domain=host,
                            path=settings.SESSION_COOKIE_PATH,
                            secure=settings.SESSION_COOKIE_SECURE or None,
                            httponly=settings.SESSION_COOKIE_HTTPONLY or None)
        return response

1
他所需要的正是该网站框架旨在适应的用例。建议“不要这样做”毫无帮助。 - jcdyer
实际上,@jcdyer,如果设置了SESSION_COOKIE_DOMAIN,他将无法使用原始的SessionMiddleware和站点框架。 - s29
十年过去了,我不认为这个还有效。我们有这样的设置,Django 3.2会报错说您不能在没有 SessionMiddleware 的情况下使用管理员,因此它无法检测到子类别。 - markwalker_

4

1
该仓库现在位于GitHub: https://github.com/ajrbyers/django-dynamicsites - Seunghoon

1
我正在使用django 3.1.4,它对我很有效。
创建一个像这样的中间件,我正在我的应用程序utilities.middleware中创建。
class CrossDomainSessionMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        if response.cookies:
            host = request.get_host()
            # check if it's a different domain
            if host not in settings.SESSION_COOKIE_DOMAIN:
                domain = ".{domain}".format(domain=host)
                for cookie in response.cookies:
                    if 'domain' in response.cookies[cookie]:
                        response.cookies[cookie]['domain'] = domain
        return response

现在将这个中间件放在settings.py中SessionMiddleware的上方。
'utilities.middlware.CrossDomainSessionMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',

确保在您的settings.py文件中有这两个变量

SESSION_COOKIE_DOMAIN = '.domain.com'
SESSION_COOKIE_NAME = 'domainsessionid'

但是,当尝试删除cookie时,那些你更改了域的cookie似乎无法被删除。你有解决方法吗?谢谢。 - Jason Liu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接