Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use this with Django-rest-framework? (Client-side OAuth2 flow?) #502

Open
ghost opened this issue Jul 17, 2023 · 6 comments
Open

Comments

@ghost
Copy link

ghost commented Jul 17, 2023

With the browsable api everything works and I can access my endpoints and admin page using the OIDC provider login, but I am unsure how to format a curl call to include authentication without the browser-session.

I am trying to set up an Oauth2 flow where the front-end gets an access token from the OIDC provider and sends that to my django rest backend to exchange it for a django token. Does that work with this package? Or should I user a server-side OAuth flow where the callback is send to my django server?

Any help is much appreciated!

@afmorielo
Copy link

Hello there! I am not one of the developers of this library, but I use it in a project with Django Rest Framework.
In my project I use what you refer to as a server-side OAuth Flow:

1) My settings.py has several variables, including:

OIDC_STORE_ACCESS_TOKEN = True

This means that after login, the access token will be stored in the Django Session object (https://mozilla-django-oidc.readthedocs.io/en/stable/settings.html#OIDC_STORE_ACCESS_TOKEN)
The Django Rest Framework is configured as follows:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'mozilla_django_oidc.contrib.drf.OIDCAuthentication',
        'rest_framework.authentication.SessionAuthentication',
        'rest_framework.authentication.TokenAuthentication',
    ),
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

2) My urls.py file have something similar to

urlpatterns = [
  path('admin/', admin.site.urls),
  path(...),
  path(...),
  path('oidc/', include('mozilla_django_oidc.urls')),
]

3) I login via https://myappurl.com/oidc/authenticate

And after login I redirect to my app home page
The access token is now stored in the Django Session object, server-side

4) I make requests to the api in the front-end normally, like a POST or GET to https://myappurl.com/api/

5) The front-end calls to the api trigger functions in the back-end and I can use the access token there

def list_products(request):
    token = request.session['oidc_access_token']
    # now I have the token and I can use it if needed

@afmorielo
Copy link

If you are using curl to make requests, there is no way that I know of to get the access token because there will not be a session created (sessions are created for browsers). Whenever I need to test something in the REST api using curl I either: 1) use Django Tokens authentication OR 2) have an access token string saved beforehand and pass it in the request HTTP header/body. But I usually avoid using curl because I can generally test the api calls in the browser.

@afmorielo
Copy link

Finally, you could of course implement every call to your OIDC Provider yourself. I use Keycloak as an OIDC Provider. But then again, if you are doing that, I don't see the reason to use this library.

@ghost
Copy link
Author

ghost commented Jul 21, 2023

Thanks for the info!

@ghost
Copy link
Author

ghost commented Sep 15, 2023

If you are using curl to make requests, there is no way that I know of to get the access token because there will not be a session created (sessions are created for browsers). Whenever I need to test something in the REST api using curl I either: 1) use Django Tokens authentication OR 2) have an access token string saved beforehand and pass it in the request HTTP header/body. But I usually avoid using curl because I can generally test the api calls in the browser.

A rather late follow-up, but did you manage to combine this package with token authentication instead of the session authentication? Or do you use token authentication without mozilla-django-oidc?

@afmorielo
Copy link

Hello there!

I believe you are referring to Django token authentication, in which each user is assigned a token stored in the app's database managed by Django. I have experience using this authentication method.

These tokens are created and managed by Django, often through the Django Admin web app. Therefore, these "Django tokens" are distinct from OAuth tokens, to the best of my knowledge. They are typically used as an authentication option in a REST API when OAuth is not in use. To use them, you include the "Django tokens" in every API request, enabling it to validate the requesting user, much like a password.

To implement OAuth tokens with the mozilla-django-oidc library, I had to switch to session authentication in Django. Fortunately, Django allows you to enable multiple authentication systems simultaneously. You can choose between them as needed by configuring the DEFAULT_AUTHENTICATION_CLASSES variable in your settings.py file. It will attempt each authentication method in order until it finds a valid one. Here's an example configuration:

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.BasicAuthentication',
        'rest_framework.authentication.TokenAuthentication',
        'rest_framework.authentication.SessionAuthentication',
    ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant