tags: [Vue, Vuetify, Flask, 前端, 后端] title: 设计一个前后端分离的管理系统 last_modified_at: 2023-8-29 slug: vue-flask-nginx-website redirect_from:
别看,没有任何价值。
其实下面这个架构很蠢,不如online-clipboard,直接用Flask托管前端build出来的静态文件就行了。而且直接手写SQLite就是纯玩具,不如SQLAlchemy。
前端请求发送给运行于443端口的nginx反向代理服务器,nginx再根据请求路径(以/api/
开头的发给后端)分别发送给前端(Vuetify 3,运行于127.0.0.1:8901
)或后端(Flask,运行于127.0.0.1:8902
),数据库使用SQLite。
使用nginx是为了规避跨域、HTTPS与Cookies问题。
域名为EU.org的永久免费域名,使用Cloudflare作为DNS服务商,DNS解析记录指向内网IP地址。
使用acme.sh自动化HTTPS证书申请,自动申请Let's Encrypt的免费证书并配置nginx。
用户访问时,nginx首先请求http://127.0.0.1:8901
,Vuetify根据Vue Router返回RootPath.vue
这一组件,其中的TypeScript代码会跳转到首页(MainView.vue
)。由于Vue Router中标记本页面需要登录,如果用户未登录,会跳转到登录页面(LoginView.vue
),否则继续访问首页。
App.vue
中为普通页面加载了一个侧边栏(Sidebar.vue
)用于在不同界面间导航。
用户点击登录时,Axios
会向后端(https://xxx.xxx.eu.org/api/user/login
)发送请求,后端返回JSON格式的响应数据,具体格式见下。
// 正常响应
{
"result": 0,
"data": {
"uid": 12,
"username": "admin",
"nickname": "管理员",
"power": [
"manage_sv",
"edit_user"
],
"user_group": [
"admin"
],
"last_login_ip": "1.2.3.4",
"email": "123@example.com",
"preferences": {}
}
}
// 错误响应
{
"result": 105, // 错误代码,定义于 Return_Code.py
"message": "用户名或密码错误" // 错误信息,定义于 Return_Code.py
}
登录成功后,会在浏览器设置两个cookie:一个是session
,会话期间有效,用于短时间记录用户信息;另一个是remember_token
,十年有效,用于长期保存用户登录状态。这里的用户信息会被Vuex保存,并被用于随后的前端用户信息查询。API的授权验证通过session
这一cookie实现。