如何使用 Django Rest Framework 创建登录 API?

Posted

技术标签:

【中文标题】如何使用 Django Rest Framework 创建登录 API?【英文标题】:How do I create a login API using Django Rest Framework? 【发布时间】:2014-02-14 13:48:13 【问题描述】:

我想使用 django rest 框架创建一个登录 api(或者使用现有的,如果它已经预先捆绑)。但是,我完全不知所措。每当我向 django rest 框架“登录”url 发送 post 请求时,它只会发回可浏览的 api 模板页面......

我的配置

urls.py

url(r'^api/v1/', include('rest_framework.urls', namespace='rest_framework'))

settings.py

REST_FRAMEWORK = 
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    )

我想要什么

请求:

POST /api/v1/login  username='name' pass='pass'

回复:

200 OK "username: 'name', 'userId': '54321'" set-cookie: sessionid="blahblah"

【问题讨论】:

我打算使用 https 和基本身份验证推出 api。但是浏览器是否有一种安全的方式来存储身份验证凭据?我不希望用户在浏览离开然后浏览回我的网站时必须不断地重新登录。由于 csrf 令牌,我想取消会话身份验证......它们在 API 中管理起来很残酷。我想吃我的蛋糕,然后…… 假设浏览器提供了一个由域绑定的持久存储,只有所有者域可以访问,我想我可以将会话 ID 存储在持久存储中而不是 cookie 中,以防止我的 API 中的 CSRF 漏洞基于网站。 你找到方法了吗? 为了以后的读者,我做了一个关于这个主题的教程:michaelwashburnjr.com/django-user-authentication @mdw7326,“找不到页面。”这是给你的教程 【参考方案1】:

看看django-rest-framework-jwt的api视图。它是一种用于创建身份验证令牌而不是 cookie 会话的实现,但您的实现将是相似的。请参阅 views.py 和 serializers.py。您可能可以不加改动地使用serializers.py,只需调整您的视图以返回正确的参数并可能设置会话cookie(不记得是否已经在身份验证中执行过)。

【讨论】:

【参考方案2】:

如果你想要这样的东西,我会做同样的事情,但是我使用令牌身份验证。

查看他们的令牌页面here

这可能不是你想要的,但我这样做的方式是(因为我将它用作移动客户端的 rest api 端点)

我可以做我的网址localhost:8000/api/users/ -H Authorization : Token 然后,浏览器可以使用您在提供的 rest 框架 url 处创建的常规登录页面

url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')

并获取“无登录”导航的令牌

url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token')

然后,如果您拨打电话等,您可以传递授权令牌。当然,这只是我的做法,它可能不是最有效的方式,但我的目标是创建一种方式,我可以通过令牌为用户提供浏览器会话身份验证和移动访问。

然后确保在您的 views.py 中添加该视图的身份验证要求。与会话认证部分几乎相同

permission_classes = (permissions.IsAdminUser,)

但也包括

authentication_classes = (authentication.TokenAuthentication,)

我希望这会有所帮助,但如果没有,祝您搜索顺利。

【讨论】:

我正在使用 django rest 框架令牌身份验证,我在提供用户名/密码后获得令牌,但我也想接收 user_id(用户的 pk)以及令牌,因此我可以保存在 localStorage 中,并在移动应用程序中需要时使用该 ID。请求令牌时获取用户主键的正确方法是什么? 使用 serializers.py 查看上述评论。您也许可以添加一个 pk 返回字段。如果那是您正在寻找的。​​span> 【参考方案3】:

当然令牌是一种很好的身份验证方式,但提问者询问的是会话身份验证。

请求:

POST /api/v1/login  username='username' password='password' 
csrftoken 值放在标题中的X-CSRFToken 中 即使有人使用email 作为用户名字段,电子邮件输入也需要username 名称参数(例如username='sample@domain.com'

回复:

302 FOUND sessionid="blahblah"
如果你没有指定next值,它会自动重定向到/accounts/profile/,这会产生404错误

【讨论】:

但是如何使用 SessionAuthentication lib 实现案例?我尝试但一直会话不保存,每当我在登录后输入新网址时,我都会得到 AnonymousUser 而不是保存的会话 在这种方法中,在哪里可以将 csrftoken 放入标头中?是否有一个单独的端点,我们使用 GET 请求获取令牌,或者我们应该将 GET 功能添加到我们的“/api/v1/login”端点?还是我错过了什么?谢谢你的回答,这是我能找到的唯一一个真正回答这个问题的人!【参考方案4】:

添加我们的观点:

from rest_framework_jwt.views import refresh_jwt_token

urlpatterns = [
    ...
    url(r'^rest-auth/', include('rest_auth.urls')),
    url(r'^rest-auth/registration/', include('rest_auth.registration.urls')),
    ...
    url(r'^refresh-token/', refresh_jwt_token),
]

【讨论】:

以上是关于如何使用 Django Rest Framework 创建登录 API?的主要内容,如果未能解决你的问题,请参考以下文章

django.test.client 上的 Django rest 框架导入错误

无法使用 Django Rest 框架发送压缩的 gzip 数据

Django 和 Django 休息框架

Django前后端分离——drf

Django REST to React - 无需密码即可获取社交身份验证令牌

尽管有 AllowAny 权限,django-rest-framework 在 POST、PUT、DELETE 上返回 403 响应