Django Rest框架令牌authentication
我已经阅读了Django Rest框架指南并完成了所有的教程。 一切似乎都是有道理的,并且应该如何工作。 我得到的基本和会话身份validation工作如上所述。 http://django-rest-framework.org/api-guide
然而,我正在努力处理文档中的令牌authentication部分,它有点缺乏,或者没有深入到教程中。
http://django-rest-framework.org/api-guide/authentication/#tokenauthentication
它说我需要为用户创build令牌,但是在models.py中指定哪里?
我的问题是:
有人可以解释第一次计时器的文档的令牌authentication部分更好一点吗?
不,不在你的models.py中 – 在模型的一面,你所需要做的就是在你的INSTALLED_APPS
包含相应的应用程序( rest_framework.authtoken
)。 这将提供一个外键给用户的令牌模型。
你需要做的是决定何时以及如何创build这些令牌对象。 在你的应用程序中,每个用户自动获得一个令牌吗? 还是只有某些授权用户? 或者只有当他们特别要求一个?
如果每个用户都应该有一个令牌,那么您链接到的页面上会有一段代码,告诉您如何设置一个信号来自动创build它们:
@receiver(post_save, sender=User) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance)
(把它放在一个models.py文件中,当Django线程启动时它会被注册)
如果令牌只能在特定时间创build,那么在您的视图代码中,您需要在适当的时间创build并保存令牌:
# View Pseudocode from rest_framework.authtoken.models import Token def token_request(request): if user_requested_token() and token_request_is_warranted(): new_token = Token.objects.create(user=request.user)
一旦令牌被创build(并保存),它将可用于身份validation。
@ ian-clelland已经提供了正确的答案。 在他的文章中只有几个小部分没有提到,所以我将logging完整的程序(我正在使用Django 1.8.5和DRF 3.2.4):
-
在创build超级用户之前执行以下操作。 否则,超级用户不会创build他/她的令牌。
-
转到settings.py并添加以下内容:
INSTALLED_APPS = ( 'rest_framework', 'rest_framework.authtoken', 'myapp', ) REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.TokenAuthentication', ) }
-
在myapp的models.py中添加下面的代码:
from django.db.models.signals import post_save from django.dispatch import receiver from rest_framework.authtoken.models import Token from django.conf import settings # This code is triggered whenever a new user has been created and saved to the database @receiver(post_save, sender=settings.AUTH_USER_MODEL) def create_auth_token(sender, instance=None, created=False, **kwargs): if created: Token.objects.create(user=instance)
或者,如果你想更明确的话,在myapp项目下创build一个名为signals.py的文件。 把上面的代码放在里面,然后在__init__.py中写入
import signals
-
打开一个控制台窗口,导航到您的项目目录,然后input以下命令:
python manage.py migrate python manage.py makemigrations
看一下你的数据库,应该创build一个名为authtoken_token的表,其中包含以下字段:key(这是标记值),created(创builddate时间),user_id(引用auth_user表的id列的外键)
-
用
python manage.py createsuperuser
创build一个超级用户。 现在,使用select * from authtoken_token;
来查看数据库中的authtoken_token表select * from authtoken_token;
,你应该看到一个新的条目已被添加。 -
使用
curl
或更简单的替代httpietesting访问您的api,我使用httpie:http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'
而已。 从现在开始,对于任何API访问,您需要在HTTP头中包含以下值( 注意空格 ):
Authorization: Token your_token_value
-
(可选)如果您提供用户名和密码,DRF还提供了返回用户令牌的function。 你所要做的就是在urls.py中包含以下内容:
from rest_framework.authtoken import views urlpatterns = [ ... url(r'^api-token-auth/', views.obtain_auth_token), ]
使用httpie来validation:
http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'
在回报体内,你应该看到:
{ "token": "blah_blah_blah" }
而已!
为了增加我的两分钱,如果你有一个处理用户创build(和激活)的自定义用户pipe理器,你也可以像这样执行这个任务:
from rest_framework.authtoken.models import Token # Other imports class UserManager(BaseUserManager): def create_user(self, **whatever_else): """ This is your custom method for creating user instances. IMHO, if you're going to do this, you might as well use a signal. """ user = self.model(**whatever_params) .... #Method ramblings that somehow gave us a user instance Token.objects.create(user=user) #You may also choose to handle this upon user activation. #Again, a signal works as well here. def activate_user(**activation_ramblings): .... #Method ramblings that somehow gave us a user instance Token.objects.create(user=user)
如果你已经创build了用户,那么你可以下载到你的terminal的Python shell中,并为你的数据库中的所有用户创build令牌。
>>>from *whatever import User >>>from rest_framework.authtoken.models import Token >>>for user in User.objects.all(): >>>... Token.objects.create(user=user)
这就是她写的所有人! 希望能帮助别人。
在Django 1.8.2和rest框架3.3.2之后,所有这些都不足以启用基于令牌的authentication。
尽pipe在django设置文件中指定了REST_FRAMEWORK设置,但基于function的视图需要@api_view装饰器:
from rest_framework.decorators import api_view @api_view(['POST','GET']) def my_view(request): if request.user.is_authenticated(): ...
否则,根本不执行令牌authentication
有一个更清晰的方式来获取用户令牌。
只需运行manage.py shell
接着
from rest_framework.authtoken.models import Token from django.contrib.auth.models import User u = User.objects.get(username='admin') token = Token.objects.create(user=u) print token.key
那么应该在DB_Schema.authtoken_token表中find一条logging
除了这里的优秀答案之外,我想提一个更好的方法来进行令牌authentication:JSON Web令牌authentication。 http://getblimp.github.io/django-rest-framework-jwt/提供的实现非常易于使用。;
这个答案更详细地解释了好处。