我可以在同一个项目中拥有 Django url 和 Vue 路由吗?
Posted
技术标签:
【中文标题】我可以在同一个项目中拥有 Django url 和 Vue 路由吗?【英文标题】:Can i have Django urls and Vue routes in the same project? 【发布时间】:2021-06-15 16:30:10 【问题描述】:我启动了一个 Django 应用程序并使用 Django-Allauth 创建了整个身份验证层,它已经具有一些功能,例如电子邮件确认、密码重置和两因素身份验证。现在我意识到,由于我的应用程序将是高度交互的并且具有许多实时功能,我将需要一个 Vue SPA 来与 Django 一起使用,所以我正在考虑在同一台服务器上创建 Vue SPA 并且域并将 Django 作为 Rest API。
这是我的问题:因为我已经使用 Django 模板和 Django url 完成了整个身份验证部分,如果我将前端的其余部分与后端分开,我是否必须重写所有内容?是否可以在同一个域上分离 Vue 应用程序和 Django 后端应用程序,其中身份验证由 Django 模板处理,其余的都是具有 vue 路由的 Vue 应用程序,所有其他交互都由 Django Rest Framework 端点处理?
所以可能是这样的:
urlpatterns = [
path('accounts/signup/', SignUpView.as_view(), name='signup'), #Django template
path('accounts/login/', LoginView.as_view(), name='login'), #Django template
...
]
这些是由 Django 视图呈现页面的唯一 Django 处理的 url。用户登录后,他们将被重定向到 VueJS 应用程序。
【问题讨论】:
这不是不可能的,但尤其是如果您希望您的 SPA 动态更改浏览器的地址(推送历史 API),那么您将需要大量非常详细的 URL 配置来使服务器正确地服务文件。至少您应该为某些部分保留某些前缀,例如/api/
用于所有 API 调用,/app/
用于您的 SPA。
您使用的 HTTP 服务器是什么?如果是 nginx,可以查看docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy
我正在使用 Ningx,是的!我正在考虑做类似/account/<django-auth-url>
的事情,其中所有内容都由Django 视图呈现,然后是/app/<Vue-routes>
,这是一个SPA,最后是从Django /api/<drf-view>
提供JSON 数据,当然,所有这些都在同一台服务器上。我觉得这比使用 Vue 和 DRF 从零开始构建我自己的身份验证要容易和安全得多,而且我对 Django 的经验比 javascript 更丰富
默认情况下,你不能在 vue 项目中使用你用 Django 构建的 Auth 和路由,特别是,如果你不想,你可以将 Django 项目中的每个视图渲染为 Vue 组件将与用户交互(但它是独立的..我的意思是它不能与其他页面交互,因为页面将在每次 url 更改时重新加载)
是的,我也想过这个问题,但我担心这会使代码更加混乱和混乱,因为我会大量使用 Vue;将其用作单独的 spa 或通过在 Django 中加载 webpack 更有意义
【参考方案1】:
我的个人意见是,为了注册、登录而保留一堆服务器端页面是不值得的……从长远来看,管理服务器端页面和前端页面是一件令人头疼的事情。但如果你喜欢这种方式,这里是我的建议。
对于身份验证,请使用 Django 身份验证。无论是服务器端 html 页面还是 API 端点。 Django auth 简单且安全。不要滚动你自己的身份验证,不要将令牌存储在本地存储中。
将这 3 个完全分开:
前端 URL(即存储在 Vue 中的路由) 后端页面 URL(即由 Django 提供的 HTML 页面) 后端 API 端点 URL(即用户从未见过的那些,只有 Vue 在后台使用它们)它们可以位于单独的域上,但也可以只是路径前缀。正如您自己在评论中所建议的那样。
现在当用户访问 BE 中的某个页面时,它将使用服务器端渲染,并且每次用户点击都是一次浏览器刷新。在您点击 FE URL 之前,您的前端代理应该将用户重定向到 FE,否则您将直接从 Django 提供 JS 文件。之后,每次用户点击都在 Vue 内部处理,无需刷新。如果用户点击了一个用于 BE 的 URL 前缀,那么 FE 需要执行类似 document.location = "/server-side/some-page
的操作。
顺便说一句,几天前我回答了与此类似的another question,也许您发现那里的答案或 cmets 有用。
因此,为了从 SPA 登录,我需要发送一个 csrf 令牌,并且为了获取该令牌,我可以创建一个 Django 视图,该视图将一个 CSRF 令牌返回给用户,以便它可以用于登录。它不会为攻击者提供攻击我的服务器的方法吗(***.com/questions/43567052/...)
我的建议是关闭 CSRF 保护,而是设置会话 cookie samesite=Lax(我认为这是新版本 Django 的默认设置)。所有主流浏览器都支持这一点,它会阻止 CSRF。
否则,您可以从其他 API 或 cookie 中读取令牌,例如 here
所以在生产中我将使用 Nginx 在同一服务器和域上拥有 Vue 应用程序和 Django 后端应用程序,但在开发中我该怎么做呢?如果我在不同的终端上运行这两个应用程序,django 不会认为 Vue 应用程序在不同的服务器上吗?
它无法理解它是什么服务器。您唯一应该关心的是 cookie 的域。它应该在您的 BE 域上设置。在本地运行时,FE 和 BE 都在域“localhost”上运行,所以应该没有问题。
【讨论】:
很好的答案,谢谢!让我想保留 Django 模板的最大原因有两个:1)我使用 Django-Allauth 进行所有与身份验证相关的事情,我不知道如何使用 SPA 中的 Django allauth 2)正如你所说,我不应该推出自己的身份验证,我不想这样做。我 100% 确定 BE 和 FE 将在同一个域中,我可以使用 Django-Allauth 或 SPA 中的标准 Django Auth 而不损失任何安全性吗?我可以用我的 SPA 中的 Django 模板做什么吗?会有多难? 你不需要做很多事情。调用 BE API 时会自动设置 Django 会话 cookie。可能 Vue 只需要一个端点来了解用户是否登录。类似/api/account/me
的东西会返回当前登录的用户信息。
非常感谢。在安全性方面,如果我从 SPA 进行身份验证,它会改变什么吗?所以基本上我唯一会存储在 localStorage 中的就是像“已验证”这样的状态,对吧?我认为您的回答让我意识到我不妨从 SPA 进行身份验证,我只是不知道 Django-Allauth 或内置的 Django 身份验证是否支持 JSON 响应,每次我尝试使用发布请求进行身份验证时我获取 HTML 响应
我认为你不应该在本地存储中存储任何东西,除非你想优化一些东西。当用户打开 SPA 时,您可以随时查看所有端点是否已登录。您通常可以轻松地将身份验证功能包装在新的 API 端点中。
CORS 与身份验证无关,它是浏览器中的保护措施,可防止其他网站向您的服务器发送 AJAX 请求。 Cookie 将在“localhost”上的每个端口之间共享。以上是关于我可以在同一个项目中拥有 Django url 和 Vue 路由吗?的主要内容,如果未能解决你的问题,请参考以下文章
试图在 django 项目的 urls 文件夹中包含 url 模式
项目中的每个 django 应用程序都应该有自己的 urls.py 吗?