vitalik / django-ninja

💨 Fast, Async-ready, Openapi, type hints based framework for building APIs
https://django-ninja.dev
MIT License
7.24k stars 430 forks source link

Integration for OAuth 2 #1015

Open Zerotask opened 10 months ago

Zerotask commented 10 months ago

Is your feature request related to a problem? Please describe. We'd like to use django-ninja with OAuth 2. At the moment we use DRF with https://github.com/jazzband/django-oauth-toolkit and we'd like to integrate django-oauth-toolkit easily with django-ninja

Describe the solution you'd like built-in integration / configuration to use this package.

eznix86 commented 9 months ago

Due to the nature of the project. This is an django app within itself.

And I think it will be hard to integrate such feature to Django Ninja. Maybe look for some alternatives or DIY then opensource it.

Maybe later when Class Based Views, a rich middleware ecosystem and/or decorators is official, then maybe we can see something like this happen. But still it requires an entire app to be built. It may be a great opportunity to build django-ninja-oauth2 for yourself and other people to benefit from it.

You can create an app and extend https://django-oauth-toolkit.readthedocs.io/en/latest/ and replace DRF views to Django Ninja views:

https://django-oauth-toolkit.readthedocs.io/en/latest/views/views.html

How it may look like.

from ninja import NinjaAPI
from ninja_oauth2 import oauth2_router
api = NinjaAPI()

api.add_router("/auth", oauth2_router)

... And the magic happens.

Zerotask commented 9 months ago

Yes, we choose the DIY way and it's very easy. I wrote this issue during our evaluation phase.

from django.http import HttpRequest
from ninja.security import HttpBearer
from oauth2_provider.contrib.rest_framework import OAuth2Authentication

class AuthBearer(HttpBearer):
    def authenticate(self, request: HttpRequest, token: str):
        auth = OAuth2Authentication()
        if auth.authenticate(request) is None:
            return None
        return token

(and then we registered it globally auth=AuthBearer())

The rest is solely handled by django-oauth-toolkit. So there was no change needed from our previous DRF API.