DRF: Auth: Overview

20th August 2020 at 2:19pm
Django REST Framework: Authentication
To-do
补充下 session 方式的具体实践,比如 CSRF token 的 cookie 怎样下发到前端。补充下 OAuth 的实践。

认证方式

DRF 的各种 认证方式

BasicAuthentication 和 TokenAuthentication

最简单的两种:

认证方式BasicAuthenticationTokenAuthentication
请求方应该带的头示例Authentication: Basic 9d2f234Authentication: Token f91de4
认证失败时返回WWW-Authenticate: Basic realm="api"WWW-Authenticate: Token
说明比较鸡肋需要为每个用户生成单独的 Token

BasicAuthentication 不用多说,现实中线上的产品应该不会有人用这种模式。即使用,也应该在 HTTPS 基础上用。

DRF 的 TokenAuthentication 比较鸡肋。django-rest-knox 指出了它存在的问题:

  • Token 是按用户的维度来设计,而不是按会话来。这意味着同一个 token 在用户的不同浏览器、设备间共享。一旦 token 在服务端被删除,则全部客户端都需要重新登陆
  • Token 在服务端的数据库中没有加密保存。一旦泄露问题很大
  • 没有内建的 token 过期机制

django-rest-knox 在实现上比 DRF 的好,但是它也 没有解决 login CSRF 的问题。这篇博客 文章 详细讲述了如何用 knox 配合 React 实现注册登陆流程。

SessionAuthentication

稍微复杂但是一样鸡肋的方式是,利用 Django 默认的 SessionAuthentication。这种机制存在几个问题:

  • 当你使用「不安全」的 HTTP 方法(PUT PATCH POSTDELETE)时,你需要带上 Django 的 CSRF token;Django 的 文档 描述了如何操作
  • 有别于 Django 默认都需要 CSRF token 的行为,DRF 针对匿名用户下的请求不需要验证 CSRF token(一般是不敏感的读请求)。但是对登录的 view 则一定要上 CSRF token 校验(参考 Web Security: CSRF 中的 Login CSRF)

RemoteUserAuthentication 和自定义认证方式

DRF 也支持 Django 的 RemoteUserAuthentication,还支持自定义认证方式。

最主流最实用的,应该是 OAuth2 和 JWT 方式。待研究。