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

时间:2014-05-15 20:06:00

标签: django django-rest-framework

我想做一个休息api,能够使用像

这样的请求登录我的Django应用程序(来自Android应用程序)
curl -X POST -d "username=myusername&password=mypassword" http://localhost:12345/rest/api-auth/login/

应返回我可以在将来的请求中使用的会话ID。我似乎应该使用SessionAuthentication身份验证方案,但它有no doc

我知道this question,但我不想使用任何其他应用。

任何建议/指针?

2 个答案:

答案 0 :(得分:5)

/api-auth/login/资源仅用于浏览api中的身份验证。 要使用会话身份验证,您必须首先创建会话。 您必须具有登录资源,该资源使用Django身份验证系统接受用户凭据并对用户进行身份验证。 在请求该资源时,客户端将获得cookie头。 必须在将来的请求中使用cookie和csrf令牌。

curl -v -X POST https://example.com/api/user/login/ -d 'username=user&password=pass'

...

> Set-Cookie:  csrftoken=TqIuhp8oEP9VY32tUDcfQyUwn3cqpYCa; expires=Fri, 15-May-2015 12:48:57 GMT; Max-Age=31449600; Path=/
> Set-Cookie:  sessionid=4yb4s456lbvd974oijbdha7k3l6g52q3; expires=Fri, 30-May-2014 12:48:57 GMT; Max-Age=1209600; Path=/

DRF也支持基本身份验证。您可以使用它进行身份验证 用户最初并创建会话。这是一个例子:

from django.contrib.auth import login

from rest_framework.authentication import BasicAuthentication, SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView


class MyBasicAuthentication(BasicAuthentication):

    def authenticate(self, request):
        user, _ = super(MyBasicAuthentication, self).authenticate(request)
        login(request, user)
        return user, _


class ExampleView(APIView):
    authentication_classes = (SessionAuthentication, MyBasicAuthentication)
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        content = {
            'user': unicode(request.user),
            'auth': unicode(request.auth),  # None
        }
        return Response(content)

答案 1 :(得分:0)

如果打算通过在POST数据上传递用户名和密码来访问某个端点,则可以执行以下操作:

<强> urls.py

urlpatterns = [
    url(r'^stuff/', views.MyView.as_view()),
    ...
]

<强> views.py

    from django.contrib.auth.models import User
    from rest_framework import viewsets
    from rest_framework.response import Response
    from rest_framework.views import APIView    
    from rest_framework.permissions import IsAuthenticated
    from rest_framework import exceptions
    from rest_framework import authentication
    from django.contrib.auth import authenticate, get_user_model
    from rest_framework.authentication import BasicAuthentication, 
SessionAuthentication


class ExampleAuthentication(authentication.BaseAuthentication):

    def authenticate(self, request):

        # Get the username and password
        username = request.data.get('username', None)
        password = request.data.get('password', None)

        if not username or not password:
            raise exceptions.AuthenticationFailed(_('No credentials provided.'))

        credentials = {
            get_user_model().USERNAME_FIELD: username,
            'password': password
        }

        user = authenticate(**credentials)

        if user is None:
            raise exceptions.AuthenticationFailed(_('Invalid username/password.'))

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


    return (user, None)  # authentication successful


class MyView(APIView):
    authentication_classes = (SessionAuthentication, ExampleAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):    
        content = {
            'user': unicode(request.user),
            'auth': unicode(request.auth),  # None
        }
        return Response(content)

<强>卷曲

curl -v -X POST http://localhost:8000/stuff/ -d 'username=my_username&password=my_password'