繁体   English   中英

基于REST API令牌的身份验证。 基本认证

[英]Rest API token based authentication. Basic Auth

我已经使用rest_framework实现了基于令牌的身份验证,到目前为止一切正常,但是我有一个问题,如果我使用basic-auth在标头中发送用户名和密码,那么为什么需要发送用户名和密码与有效载荷。 当我发送包含有效载荷的请求时,在正文部分包含用户名和密码的有效负载,而请求标头中没有用户名和密码,我得到以下响应:

{
  "detail": "CSRF Failed: CSRF token missing or incorrect."
}

当我在标头中发送用户名和密码而不发送带有有效负载的用户名和密码时,我得到以下响应:

{
  "detail": "Invalid username/password."
}

与有效负载一起发送时,为什么需要在标头部分发送用户名和密码。 我不太确定这个概念。 谁能解释并向我展示正确的方法。 我已经使用了这个参考

以下是我的代码: authuser.py

"""Authentication classes for Django Rest Framework.
Classes:
    ExpiringTokenAuthentication: Authentication using extended authtoken model.
"""

from rest_framework import exceptions
from rest_framework.authentication import TokenAuthentication

from rest_framework_expiring_authtoken.models import ExpiringToken


class ExpiringTokenAuthentication(TokenAuthentication):

    """
    Extends default token auth to have time-based expiration.
    Based on http://stackoverflow.com/questions/14567586/
    """

    model = ExpiringToken

    def authenticate_credentials(self, key):
        """Attempt token authentication using the provided key."""
        if key == "2572e6dbe3b2e150764cd72712713b2975785197":
            token = self.model.objects.get(key=key)
        else:
            try:
                token = self.model.objects.get(key=key)
            except self.model.DoesNotExist:
                raise exceptions.AuthenticationFailed('Invalid token')

            if not token.user.is_active:
                raise exceptions.AuthenticationFailed('User inactive or deleted')

            #if token.expired():
             #   raise exceptions.AuthenticationFailed('Token has expired')

        return (token.user_id, token)

查看.py

 class ObtainExpiringAuthToken(ObtainAuthToken):

    """View enabling username/password exchange for expiring token."""
    model = ExpiringToken
    def post(self, request):
        try:
            payload=json.loads(request.body)
        except:
            return Response({'success':False,'message':'Invalid Payload.'})
        """Respond to POSTed username/password with token."""
        serializer = AuthTokenSerializer(data=request.data)
        if serializer.is_valid():
            token, _ = ExpiringToken.objects.get_or_create(
                user=serializer.validated_data['user']
            )
            if token.expired():
                # If the token is expired, generate a new one.
                token.delete()
                token = ExpiringToken.objects.create(
                    user=serializer.validated_data['user']
                )

            try:
                user = User.objects.get(id=token.user_id)
            except:
                return Response({'success':False,'message':'User does not exists.'})
    return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

get_expiring_auth_token = ObtainExpiringAuthToken.as_view()

models.py:

@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)

class ExpiringToken(Token):

    """Extend Token to add an expired method."""

    class Meta(object):
        proxy = True

    def expired(self):
        """Return boolean indicating token expiration."""
        now = timezone.now()
        #if self.created < now - token_settings.EXPIRING_TOKEN_LIFESPAN:
         #   return True
        return True

settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ),
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.JSONParser',
    )
}

出现此错误的唯一可能方法是启用SessionAuthentication 默认情况下已全局启用。

http://www.django-rest-framework.org/api-guide/authentication/#setting-the-authentication-scheme

请仔细检查您的设置或在您的视图类中设置适当的设置,以覆盖全局设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM