Flask 博客后台权限设计:从登录保护到自动发布接口 Token 校验
个人博客看起来功能简单,但只要有后台登录、文章发布、图片上传和自动化接口,就已经有了清晰的权限边界。后台给人用,自动发布接口给程序用,两者不能混在一起。否则后期接入 Codex 自动发文、搜索平台提交、广告管理时,很容易把权限做乱。
这篇文章以 Flask 博客为例,整理一套适合个人站点的权限设计方法:后台页面用登录态和 CSRF 保护,自动化发布接口用独立 Token,敏感配置放在 .env,线上排查通过日志和健康检查完成。
后台页面必须走登录态
后台文章管理、分类管理、广告配置、站点配置,都应该放在登录保护之后。Flask 常见做法是使用 Flask-Login,把管理员登录后的身份保存在 session 里。
@app.route('/admin/articles')
@login_required
def admin_articles():
...
这样做的好处是清晰:人访问后台,必须先登录。不要为了自动化方便,把后台表单接口暴露成无需登录的 POST 地址。
表单提交要保留 CSRF 校验
后台表单除了登录态,还应该做 CSRF 校验。原因很简单:管理员登录后,浏览器会自动带上 cookie,如果没有 CSRF 保护,第三方页面可能诱导浏览器向后台提交请求。
对于文章编辑、删除、广告配置这类操作,CSRF 是低成本但很关键的防线。自动化发布不要绕过这套后台表单,而应该单独设计机器接口。
自动发布接口不要复用管理员密码
Codex 自动发布文章时,不适合模拟管理员登录,也不适合在脚本里保存后台账号密码。更稳妥的方式是提供一个专门的接口,例如:
POST /api/articles/publish
Authorization: Bearer <AUTO_PUBLISH_TOKEN>
这个 Token 只用于发布文章,和管理员登录密码分开。以后如果 Token 泄露,只需要更换 .env 里的 AUTO_PUBLISH_TOKEN,不用改管理员账号。
Token 要放在环境变量里
Token 不应该写进 Git,也不应该硬编码在 Python 文件里。线上服务器 .env 可以放:
AUTO_PUBLISH_TOKEN=一串强随机密钥
本机 Codex 自动化环境也放同一份 Token:
ONLINE_BLOG_PUBLISH_URL=http://你的站点/api/articles/publish
AUTO_PUBLISH_TOKEN=同服务器一致的密钥
这样代码可以公开维护,密钥只存在部署环境中。
接口里要做字段校验
自动发布接口不能因为“调用方是自己”就完全相信 payload。至少要检查这些字段:标题是否为空,摘要是否过长,正文是否为空,分类是否存在,状态是否只能是 draft、submitted、published,标签是否是列表。
校验失败返回 400,鉴权失败返回 401,数据库唯一冲突返回 409。这样自动化日志才容易判断问题在哪。
发布成功后返回 slug
自动化发文后,下一步通常要提交搜索平台收录,所以发布接口应该返回文章 slug。脚本拿到 slug 后就能拼出公开 URL,而不是自己猜路径。
健康检查要独立存在
线上排查时,/healthz 很有用。它不需要登录,只返回应用是否能正常响应。如果服务器内部访问 127.0.0.1:8000/healthz 正常,但公网访问失败,问题多半在 Nginx、安全组、代理或外部网络。如果两边都失败,再看 Flask/Gunicorn 日志。
总结
个人 Flask 博客的权限设计不需要复杂,但边界要清楚:人用后台登录,表单保留 CSRF;机器用独立 Token,接口只开放必要能力;密钥放环境变量,发布结果返回 slug;健康检查和日志用于排查。这样的结构足够支撑长期自动化发文,也不会把后台账号密码暴露给脚本。
参考资料:Flask 官方文件上传文档 https://flask.palletsprojects.com/en/stable/patterns/fileuploads/