{"title":"如何从 Apache 对 Django 的用户数据库进行认证","version":"5.2","locale":"zh-hans","docname":"howto/deployment/wsgi/apache-auth","url":"/zh-hans/5.2/howto/deployment/wsgi/apache-auth/","canonical":"https://djangodocs.dev/zh-hans/5.2/howto/deployment/wsgi/apache-auth/","summary":"使用 Apache 时，保持多个身份认证数据同步是一个常见的问题，你可以让 Apache 直接使用 Django 的验证系统。这要求 Apache 版本 >= 2.2，且 mod_wsgi >= 2.0。","html":"<h1>如何从 Apache 对 Django 的用户数据库进行认证<a class=\"heading-anchor\" href=\"#how-to-authenticate-against-django-s-user-database-from-apache\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>使用 Apache 时，保持多个身份认证数据同步是一个常见的问题，你可以让 Apache 直接使用 Django 的 <a class=\"reference internal\" href=\"/zh-hans/5.2/topics/auth/\"><span class=\"doc\">验证系统</span></a>。这要求 Apache 版本 &gt;= 2.2，且 mod_wsgi &gt;= 2.0。例如这样：</p>\n<ul class=\"simple\">\n<li><p>仅为已授权的用户直接从 Apache 提供 static/media 文件。</p></li>\n<li><p>仅为有特定权限的 Django 用户提供 <a class=\"reference external\" href=\"https://subversion.apache.org/\">Subversion</a> 仓库访问。</p></li>\n<li><p>允许某些用户连接到 <a class=\"reference external\" href=\"https://httpd.apache.org/docs/2.2/mod/mod_dav.html\">mod_dav</a> 创建的 WebDAV 共享。</p></li>\n</ul>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>若你已安装了一个 <a class=\"reference internal\" href=\"/zh-hans/5.2/topics/auth/customizing/#auth-custom-user\"><span class=\"std std-ref\">自定义用户模型</span></a>，且想使用其默认认证处理器，它必须要支持 <code class=\"docutils literal notranslate\">is_active</code> 属性。若你想使用用户组授权，自定义用户必须有个关联名 'groups`，指向一个拥有 'name' 字段的关联对象。若自定义的无法满足上述要求，你也可以指定自定义 mod_wsgi 认证处理器。</p>\n</aside>\n<section id=\"authentication-with-mod-wsgi\">\n<h2>用 <code class=\"docutils literal notranslate\">mod_wsgi</code> 进行授权认证<a class=\"heading-anchor\" href=\"#authentication-with-mod-wsgi\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>以下配置文件中的 <code class=\"docutils literal notranslate\">WSGIApplicationGroup %{GLOBAL}</code> 假定 Apache 实例仅运行了一个 Django 应用。若你运行了不止一个 Django 应用，请参考 mod_wigi 文档的 <a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/en/develop/user-guides/configuration-guidelines.html#defining-application-groups\">定义应用集群</a> 章节获取更多配置信息。</p>\n</aside>\n<p>确保 mod_wsgi 已经安装并激活，并且你已经按照步骤设置了 <a class=\"reference internal\" href=\"/zh-hans/5.2/howto/deployment/wsgi/modwsgi/\"><span class=\"doc\">Apache 的 mod_wsgi</span></a>。</p>\n<p>然后，编辑 Apache 配置，添加只允许授权用户查看的位置：</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">WSGIScriptAlias</span> / <span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n<span class=\"nb\">WSGIPythonPath</span> <span class=\"sx\">/path/to/mysite.com</span>\n\n<span class=\"nb\">WSGIProcessGroup</span> %{GLOBAL}\n<span class=\"nb\">WSGIApplicationGroup</span> %{GLOBAL}\n\n<span class=\"nt\">&lt;Location</span> <span class=\"s\">&quot;/secret&quot;</span><span class=\"nt\">&gt;</span>\n    <span class=\"nb\">AuthType</span> Basic\n    <span class=\"nb\">AuthName</span> <span class=\"s2\">&quot;Top Secret&quot;</span>\n    <span class=\"nb\">Require</span> valid-user\n    <span class=\"nb\">AuthBasicProvider</span> wsgi\n    <span class=\"nb\">WSGIAuthUserScript</span> <span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n<span class=\"nt\">&lt;/Location&gt;</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">WSGIAuthUserScript</code> 指令告诉 mod_wsgi 在指定 wsgi 脚本中执行 <code class=\"docutils literal notranslate\">check_password</code> 函数，并传递从提示符获取的用户名和密码。在本例中， <code class=\"docutils literal notranslate\">WSGIAuthUserScript</code> 与 <code class=\"docutils literal notranslate\">WSGIScriptAlias</code> 一样，后者 <a class=\"reference internal\" href=\"/zh-hans/5.2/howto/deployment/wsgi/\"><span class=\"doc\">由 django-admin startproject 创建</span></a>，定义了应用。</p>\n<aside class=\"admonition-using-apache-2-2-with-authentication admonition\" role=\"note\">\n<p class=\"admonition-title\">使用带身份验证的 Apache 2.2</p>\n<p>确认 <code class=\"docutils literal notranslate\">mod_auth_basic</code> 和 <code class=\"docutils literal notranslate\">mod_authz_user</code> 被加载了。</p>\n<p>这些可能被静态编译进 Apache，或者用 LoadModule 在 <code class=\"docutils literal notranslate\">httpd.conf</code> 动态加载它们：</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">LoadModule</span> auth_basic_module modules/mod_auth_basic.so\n<span class=\"nb\">LoadModule</span> authz_user_module modules/mod_authz_user.so\n</code></pre></div>\n</aside>\n<p>最后，编辑 WSGI 脚本 <code class=\"docutils literal notranslate\">mysite.wsgi</code>，通过导入 <code class=\"docutils literal notranslate\">check_password</code> 函数，将 Apache 的认证授权机制接续在你站点的授权机制之后:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span> <span class=\"nn\">os</span>\n\nos<span class=\"o\">.</span>environ<span class=\"p\">[</span><span class=\"s2\">&quot;DJANGO_SETTINGS_MODULE&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;mysite.settings&quot;</span>\n\n<span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.handlers.modwsgi</span> <span class=\"kn\">import</span> check_password\n\n<span class=\"kn\">from</span> <span class=\"nn\">django.core.handlers.wsgi</span> <span class=\"kn\">import</span> WSGIHandler\n\napplication <span class=\"o\">=</span> WSGIHandler<span class=\"p\">()</span>\n</code></pre></div>\n<p>以 <code class=\"docutils literal notranslate\">/secret/</code> 开头的请求现在会要求用户认证。</p>\n<p>mod_wsgi <a class=\"reference external\" href=\"https://modwsgi.readthedocs.io/en/develop/user-guides/access-control-mechanisms.html\">可达性控制机制文档</a> 提供了其它授权机制和方法的更多细节和信息。</p>\n<section id=\"authorization-with-mod-wsgi-and-django-groups\">\n<h3>利用 <code class=\"docutils literal notranslate\">mod_wsgi</code> 和 Django 用户组(groups)进行授权<a class=\"heading-anchor\" href=\"#authorization-with-mod-wsgi-and-django-groups\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>mod_wsgi 也提供了将组成员限制至特定路径的功能。</p>\n<p>在本例中，Apache 配置应该看起来像这样：</p>\n<div class=\"code-block\" data-language=\"apache\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Apache</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Apache code\"><code><span class=\"nb\">WSGIScriptAlias</span> / <span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n\n<span class=\"nb\">WSGIProcessGroup</span> %{GLOBAL}\n<span class=\"nb\">WSGIApplicationGroup</span> %{GLOBAL}\n\n<span class=\"nt\">&lt;Location</span> <span class=\"s\">&quot;/secret&quot;</span><span class=\"nt\">&gt;</span>\n    <span class=\"nb\">AuthType</span> Basic\n    <span class=\"nb\">AuthName</span> <span class=\"s2\">&quot;Top Secret&quot;</span>\n    <span class=\"nb\">AuthBasicProvider</span> wsgi\n    <span class=\"nb\">WSGIAuthUserScript</span> <span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n    <span class=\"nb\">WSGIAuthGroupScript</span> <span class=\"sx\">/path/to/mysite.com/mysite/wsgi.py</span>\n    <span class=\"nb\">Require</span> <span class=\"k\">group</span> secret-agents\n    <span class=\"nb\">Require</span> valid-user\n<span class=\"nt\">&lt;/Location&gt;</span>\n</code></pre></div>\n<p>要支持 <code class=\"docutils literal notranslate\">WSGIAuthGroupScript</code> 指令，同样的 WSGI 脚本 <code class=\"docutils literal notranslate\">mysite.wsgi</code> 必须也导入 <code class=\"docutils literal notranslate\">groups_for_user</code> 函数，函数会返回用户所属用户组的列表。</p>\n<div class=\"code-block\" data-language=\"python\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.auth.handlers.modwsgi</span> <span class=\"kn\">import</span> check_password<span class=\"p\">,</span> groups_for_user\n</code></pre></div>\n<p>对 <code class=\"docutils literal notranslate\">/secret</code> 的请求现在也会要求用户是 &quot;secret-agents&quot; 用户组的成员。</p>\n</section>\n</section>","rootId":"how-to-authenticate-against-django-s-user-database-from-apache","toc":[{"title":"用 mod_wsgi 进行授权认证","anchor":"authentication-with-mod-wsgi","children":[{"title":"利用 mod_wsgi 和 Django 用户组(groups)进行授权","anchor":"authorization-with-mod-wsgi-and-django-groups","children":[]}]}],"breadcrumbs":[{"docname":"howto/index","title":"如何引导","url":"/zh-hans/5.2/howto/"},{"docname":"howto/deployment/index","title":"如何部署 Django","url":"/zh-hans/5.2/howto/deployment/"},{"docname":"howto/deployment/wsgi/index","title":"如何使用 WSGI 进行部署","url":"/zh-hans/5.2/howto/deployment/wsgi/"}],"prev":{"docname":"howto/deployment/wsgi/modwsgi","title":"如何使用 Apache 和 mod_wsgi 托管 Django","url":"/zh-hans/5.2/howto/deployment/wsgi/modwsgi/"},"next":{"docname":"howto/deployment/asgi/index","title":"如何使用 ASGI 来部署","url":"/zh-hans/5.2/howto/deployment/asgi/"},"formats":{"html":"/zh-hans/5.2/howto/deployment/wsgi/apache-auth/","markdown":"/zh-hans/5.2/howto/deployment/wsgi/apache-auth.md","json":"/zh-hans/5.2/howto/deployment/wsgi/apache-auth.json"},"source":"https://github.com/django/django/blob/stable/5.2.x/docs/howto/deployment/wsgi/apache-auth.txt","official":"https://docs.djangoproject.com/zh-hans/5.2/howto/deployment/wsgi/apache-auth/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}