2

i'm building simple API with Django 2.1.8 and provide security with Django OAuth Toolkit. I've reached the point where user can use api only after authorization but i want to limit his acctions only to his data.

I've built authorization using oauth2 which returns me access token.

models.py

class Client(AbstractUser):

    email = models.EmailField(
        verbose_name='email adress',
        max_length= 255,
        unique=True,
    )
    location = models.CharField(max_length=500, default="")

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    objects = ClientManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['location']

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

views.py

class SingleClientView(generics.RetrieveAPIView):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer
    permission_classes = [IsAuthenticated, TokenHasReadWriteScope]

Is there any possibility to connect returned token with user model, so every time someone would use API it filter if user matches required data? Or does oauth toolkit automatically and how to acces it?

Champer
  • 95
  • 5

1 Answers1

2

You have to add oauth2_provider.middleware.OAuth2TokenMiddleware in your middlewares in settings.py file. This will automatically attach the user with request to which token belongs and you can access it from request like request.user

You can modify your view accordingly.

class SingleClientView(generics.RetrieveAPIView):
    queryset = Client.objects.all()
    serializer_class = ClientSerializer
    permission_classes = [IsAuthenticated, TokenHasReadWriteScope]

    def get_object(self):
        return self.request.user
        # or any similar logic here..
Nafees Anwar
  • 6,324
  • 2
  • 23
  • 42
  • I've done it and whenever i try to access request.user it gives me : **Client object has no attribute get** . How should look _get_ method in my custom Client model? – Champer Apr 02 '19 at 18:36
  • It looks like you are calling get method on Client object. Can you post what (code) exactly you are trying? – Nafees Anwar Apr 02 '19 at 18:39
  • I got _access token_ and now i'm trying to run this function: `def test(request): return request.user` to see if it really works. I guess it has something to do with that error here in **django/middleware/clickjacking.py** file: `if response.get('X-Frame-Options') is not None: return response` – Champer Apr 02 '19 at 18:41
  • It gives **Client object has no attribute get**. – Champer Apr 02 '19 at 18:45
  • You are returning `return request.user` from `test` function. It is not supposed to work. You have to return an `HttpResponse` object. – Nafees Anwar Apr 02 '19 at 18:48
  • Oh boy you are tottaly right, i've mistaken it with Flask's return :D Thank you so much, it really works! – Champer Apr 02 '19 at 18:51