Django Rest框架令牌认证

Pro*_*eus 71 python django django-rest-framework

我已经阅读了Django Rest Framework指南并完成了所有教程.一切似乎都有意义,并且应该如何运作.我按照描述进行基本和会话认证. http://django-rest-framework.org/api-guide

但是,我正在努力使用文档的令牌认证部分,它有点缺乏或没有深入到教程的深度.
http://django-rest-framework.org/api-guide/authentication/#tokenauthentication

它说我需要为用户创建令牌,但是在models.py中说明了哪里?

我的问题是:

有人可以为第一个计时器解释文档的令牌认证部分吗?

Che*_*eng 79

@ ian-clelland已经提供了正确的答案.他的帖子里只提到了一些小件,所以我要记录完整的程序(我使用的是Django 1.8.5和DRF 3.2.4):

  1. 创建超级用户之前,请执行以下操作.否则,超级用户不会创建他/她的令牌.

  2. 转到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',
        )
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. myappmodels.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)
    
    Run Code Online (Sandbox Code Playgroud)

    或者,如果您想更明确,请在myapp项目下创建名为signals.py的文件.将上面的代码放在其中,然后在__init__.py中写入import signals

  4. 打开控制台窗口,导航到项目目录,然后输入以下命令:

    python manage.py migrate
    python manage.py makemigrations
    
    Run Code Online (Sandbox Code Playgroud)

    看看你的数据库,应该使用以下字段创建一个名为authtoken_token的表:key(这是令牌值),创建(创建它的日期时间),user_id(引用auth_user表的id列的外键)

  5. 创建一个超级用户python manage.py createsuperuser.现在,看看数据库中的authtoken_tokenselect * from authtoken_token;,您应该看到添加了一个新条目.

  6. 使用curl或更简单的替代httpie来测试对api的访问,我使用的是httpie:

    http GET 127.0.0.1:8000/whatever 'Authorization: Token your_token_value'
    
    Run Code Online (Sandbox Code Playgroud)

    而已.从现在开始,对于任何API访问,您需要在HTTP标头中包含以下值(注意空白):

    Authorization: Token your_token_value
    
    Run Code Online (Sandbox Code Playgroud)
  7. (可选)如果提供用户名和密码,DRF还可以返回用户的令牌.您所要做的就是在urls.py中包含以下内容:

    from rest_framework.authtoken import views
    
    urlpatterns = [
        ...
        url(r'^api-token-auth/', views.obtain_auth_token),
    ]
    
    Run Code Online (Sandbox Code Playgroud)

    使用httpie验证:

    http POST 127.0.0.1:8000/api-token-auth/ username='admin' password='whatever'
    
    Run Code Online (Sandbox Code Playgroud)

    在返回机构中,您应该看到:

    {
        "token": "blah_blah_blah"
    }
    
    Run Code Online (Sandbox Code Playgroud)

而已!


Ian*_*and 63

不,不是在你的models.py中 - 在模型方面,你需要做的就是在你的模型中包含相应的app(rest_framework.authtoken)INSTALLED_APPS.这将提供一个外键键入用户的令牌模型.

您需要做的是决定何时以及如何创建这些令牌对象.在您的应用中,每个用户都会自动获得令牌吗?或者只有某些授权用户?或者只有当他们特别要求一个?

如果每个用户都应该有一个令牌,那么您链接到的页面上会显示一段代码,告诉您如何设置信号以自动创建它们:

@receiver(post_save, sender=User)
def create_auth_token(sender, instance=None, created=False, **kwargs):
    if created:
        Token.objects.create(user=instance)
Run Code Online (Sandbox Code Playgroud)

(把放在models.py文件中的任何地方,它将在Django线程启动时注册)

如果只应在特定时间创建令牌,那么在视图代码中,您需要在适当的时间创建并保存令牌:

# 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)
Run Code Online (Sandbox Code Playgroud)

创建(并保存)令牌后,它将可用于身份验证.

  • @244boy 将 `create_auth_token` 设置为 [信号处理程序](https://docs.djangoproject.com/en/2.0/topics/signals/),以便每当保存 `User` 时(因此是 `post_save`), `create_auth_token` 被调用。信号是 django 的内部生命周期事件处理机制。 (2认同)

小智 16

在Django 1.8.2和rest framework 3.3.2之后,上述所有内容都不足以启用基于令牌的身份验证.

虽然在django设置文件中指定了REST_FRAMEWORK设置,但是基于函数的视图需要@api_view装饰器:

from rest_framework.decorators import api_view

@api_view(['POST','GET'])
def my_view(request):
    if request.user.is_authenticated():
       ...
Run Code Online (Sandbox Code Playgroud)

否则,根本不执行令牌认证

  • 尽管赞成很少,但这个答案增加了一个非常有用的观点:没有@api_view装饰器,视图将不会使用令牌身份验证.也许它可以添加到所选答案中. (2认同)

par*_*enz 14

只是为了增加我的两分钱,如果你有一个处理用户创建(和激活)的自定义用户管理器,你也可以像这样执行这个任务:

from rest_framework.authtoken.models import Token
# Other imports

class UserManager(BaseUserManager):

    def create_user(self, **kwargs):
        """
        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(**kwargs) ...
        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(**kwargs):
        # user = ...
        Token.objects.create(user=user)
Run Code Online (Sandbox Code Playgroud)

如果您已经创建了用户,那么您可以直接进入终端中的python shell并为数据库中的所有用户创建令牌.

>>> from django.contrib.auth.models import User
>>> from rest_framework.authtoken.models import Token 
>>> for user in User.objects.all():
>>> ...    Token.objects.create(user=user)
Run Code Online (Sandbox Code Playgroud)

这就是她写的所有人!希望能帮助别人.


小智 10

有一种更简洁的方法来获取用户令牌.

只需运行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
Run Code Online (Sandbox Code Playgroud)

然后应在表DB_Schema.authtoken_token中找到记录


Def*_*_Os 6

除了这里的优秀答案之外,我还想提一下更好的令牌认证方法:JSON Web令牌认证.http://getblimp.github.io/django-rest-framework-jwt/提供的实现非常易于使用.

这个答案中更详细地解释了这些好处.