django1.8 api - 如何用密钥进行身份验证

时间:2016-05-18 20:21:39

标签: django

我想允许django用户使用api URL中的密钥进行身份验证。 我还没有设置OAUTH所以我猜密钥可能是一个sesion密钥或一个摘要密钥。 我有2个问题。 我已尝试发送此请求:

http://192.166.166.11:8000/api?task=search&term=115&csrf_token=s69WAIZqlCTur1XZQr72QhCc7fzqaRtM

首先,我尝试使用 csrf_token ,但它不起作用。 它将我带到登录页面。 其次,我不知道如何检索其他用户的csrf_token(管理员正试图获取他们的csrf_tokens)。

我的尝试:

x = User.objects.get(username='someone')
x.get_session_auth_hash()

为我提供了用户的身份验证哈希,但它是一个不同的值。

有人可以指导我解决这两个问题吗?

3 个答案:

答案 0 :(得分:1)

您正在创建基于令牌的身份验证。您已经提到OAUTH作为一个选项,我强烈建议您使用其中一个现有的实现,如django-oauth-toolkit。但是,您也可以创建自己的快速解决方案来创建基于令牌的身份验证。

免责声明:此仅供演示之用。不要在任何现有项目中复制它。它会使您的应用程序容易受到攻击。

首先,我们创建一个处理身份验证令牌的附加模型:

/auth_tokens/models.py

from django.db import models
from django.conf import settings

import string, random

def random_string(length = 64, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits):
    return ''.join(random.choice(chars) for x in range(length))

class AuthToken(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    token = models.CharField(max_length=64, default=random_string)

/auth_tokens/middleware.py

from auth_tokens.models import AuthToken

class AuthTokenMiddleware:
    def process_request(self, request): 
        token = request.GET.get('auth', None)
        if not token: 
            return
        token = AuthToken.objects.get(token=token)
        request.user = token.user
        return request

在您的settings.MIDDLEWARE_CLASSES中加入中间件可让您将?token=<token>添加到您的网址以登录您的用户。

答案 1 :(得分:1)

我最终使用了令牌身份验证: http://www.django-rest-framework.org/api-guide/authentication/

所以我想分享工作流程。

首先,您需要进行设置。在settings.py中,修改INSTALLED_APPS并添加REST_FRAMEWORK,如文档中所示。 然后你需要运行python manage.py syncdb,因为它需要添加一些表。 然后,您需要向urls.py添加一些URL来路由api。 您可以使用以下代码创建和检索令牌:

from rest_framework.authtoken.models import Token
token = Token.objects.create(user=User.objects.get(username='john'))
print token.key

最后,您必须修改视图,这取决于您使用的是基于函数还是基于类的视图。 这是我使用的基于函数的视图:

from rest_framework.authentication import TokenAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.decorators import authentication_classes, permission_classes
from rest_framework.decorators import api_view

@api_view(['GET', 'POST'])
@authentication_classes((TokenAuthentication,))
@permission_classes((IsAuthenticated,))
@login_required
def mybooks(request):
    entries = Book.objects.all()
    return render(request, 'mybooks.html', {'entries': entries})

最后,要测试一下:

import requests
token = '243124c52f7583e320d043c4395bd99f63344035'
headers = {'Authorization' : 'Token {}'.format(token)}
page = requests.post('http://127.0.0.1:8000/mybooks/', headers=headers)
print page.content

请注意,在我的情况下,我不需要定义普通序列化,因为我有一个高级自定义序列化,这不是这里的主题。

答案 2 :(得分:0)

Django没有提供开箱即用的API密钥。 使用Tastypie等API提供程序来使用此功能