简体   繁体   English

如何访问(询问)用户登录令牌

[英]How to access(ask) token for user login

I have used Django Rest Framework for Rest API and django-oauth-toolkit for token based authentication. 我已经使用Django Rest Framework for Rest API和django-oauth-toolkit进行基于令牌的身份验证。 I have designed and api for user registration. 我已经为用户注册设计了api。 When user is registered, a token is generated and saved to the database. 注册用户后,将生成令牌并将其保存到数据库。 I want user login from that token. 我希望用户从该令牌登录。 I mean a token based authentication because i want to develop a mobile application. 我的意思是基于令牌的身份验证,因为我想开发移动应用程序。 I can get access_token using curl when sending request for logging in but how do i implement in view so that app sends a post request to 127.0.0.1:8000/o/token asking for the token so that the request contains username, password, client_id and client_secret. 我可以在发送登录请求时使用curl获取access_token,但是如何在视图中实现,以便应用将发布请求发送至127.0.0.1:8000/o/token要求令牌,以便该请求包含用户名,密码,client_id和client_secret。 The server then receives the credentials and if they are valid it returns the access_token. 然后,服务器会收到凭据,如果凭据有效,则它将返回access_token。 The rest of the time it should query the server using that token. 其余时间,它将使用该令牌查询服务器。

views.py views.py

class UserLoginAPI(APIView):
    permission_classes = [AllowAny]
    serializer_class = UserLoginSerializer

    def post(self, request, *args, **kwargs):
        access_token = AccessToken.objects.get(token=request.POST.get('access_token'), expires__gt=timezone.now()) # error is shown here. I get None
        data = request.data
        serializer = UserLoginSerializer(data=data)
        if serializer.is_valid(raise_exception=True):
            new_data = serializer.data
            return Response(new_data, status=status.HTTP_200_OK)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

serializers.py serializers.py

class UserCreateSerializer(ModelSerializer):
    class Meta:
        model = User
        extra_kwargs = {"password": {"write_only": True}}

    def create(self, validated_data):
        username = validated_data['username']
        first_name = validated_data['first_name']
        last_name = validated_data['last_name']
        email = validated_data['email']
        password = validated_data['password']
        confirm_password = validated_data['password']
        user_obj = User(
                username = username,
                first_name = first_name,
                last_name = last_name,
                email = email
            )
        user_obj.set_password(password)
        user_obj.save()
        if user_obj:
            expire_seconds = oauth2_settings.user_settings['ACCESS_TOKEN_EXPIRE_SECONDS']
            scopes = oauth2_settings.user_settings['SCOPES']

            application = Application.objects.get(name="Foodie")
            expires = datetime.now() + timedelta(seconds=expire_seconds)
            access_token = AccessToken.objects.create(user=user_obj, 
                                                    application=application,
                                                    token = generate_token(),
                                                    expires=expires, 
                                                    scope=scopes)
        return validated_data


class UserLoginSerializer(ModelSerializer):
    # token = CharField(allow_blank=True, read_only=True)
    username = CharField()
    class Meta:
        model = User
        fields = [
            'username',
            'password',
            # 'token',

        ]
        extra_kwargs = {"password":
                            {"write_only": True}
                            }

So if you want a api to get token depend on username and password will look like this: 因此,如果您想让api依靠用户名和密码来获取令牌,则将如下所示:

def get_token(request):
    username = request.POST.get("username")
    password = request.POST.get("password")
    .... # other parameters
    try:
        user = User.objects.get(username=username, password=password)
    except ObjectDoesNotExist:
        return HttpResponse("Can't find this user")
    else:
        try:
            access_token = AccessToken.objects.get(user=user)
        except ObjectDoesNotExist:
            return HttpResponse("Haven't set any token")
        else:
            return HttpResponse(access_token)

If you want to use DRF to handle this: 如果要使用DRF处理此问题:

@api_view(['POST'])
def get_token(request):
    # get token by query just like above
    serializer = TokenSerializer(data=access_token.token) #you can pass more parameters to data if you want, but you also have to edit your TokenSerializer
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Your TokenSerializer: 您的TokenSerializer:

class TokenSerializer(ModelSerializer):
    class Meta:
        model = AccessToken
        field = (token,)

EDIT 编辑

It depends 这取决于

  • Web, you post your username and password to login api, your browser store session in your cookies. 在网络上,您发布用户名和密码以登录api,即cookie中的浏览器存储会话。
  • Mobile, you post your username and password to login api, server response the token then you store it in your mobile, maybe keychain when you are developing IOS app.And send it as http header when you want to access the server, how-can-i-get-all-the-request-headers-in-django 移动版,您输入用户名和密码登录api,服务器响应令牌,然后将其存储在您的移动版中(可能是开发IOS应用程序时的钥匙串)。当您要访问服务器时将其作为http标头发送, 如何我在Django中获取所有请求标头

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

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