> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rownd.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Django (Python)

> Integrate Rownd instant accounts and authentication into your Django-backed project.

### Installation

Install via pip:

```bash theme={null}
pip install rownd-django
```

Or, add the `rownd-django` package to your dependencies. In `requirements.txt`,
this would look like:

```txt theme={null}
rownd-django>=1.0.0
```

<Info>
  This plugin only works with Django v3 and above. We strongly recommend
  upgrading if you're using something older. If you can't for some reason,
  please [get in
  touch](mailto:support@rownd.io?subject=Django%soSDK:%20Request%20for%20older%20version%20support).
</Info>

Next, add the Rownd app and authentication backend to your Django `settings.py`
file.

```py theme={null}
INSTALLED_APPS = [
    ...
    'rownd_django',
]

AUTHENTICATION_BACKENDS = [
    'rownd_django.auth.backend.RowndAuthenticationBackend',
    'django.contrib.auth.backends.ModelBackend'
]
```

If you're using Django REST Framework, then add the Rownd authentication class
to your `REST_FRAMEWORK` settings.

```py theme={null}
REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rownd_django.auth.backend.RowndApiAuthentication',
    ]
}
```

Finally, add your Rownd app credentials to your Django `settings.py` file. You
can obtain these from the [Rownd dashboard](https://app.rownd.io). These
credentials enable the Rownd authentication backend to communicate with the
Rownd API.

```py theme={null}
ROWND = {
    'APP_KEY': '<your app key>',
    'APP_SECRET': '<your app secret>',
}
```

#### A note on Google Sign-in

If you plan to use Google sign-in, you'll need to add or update one last configuration item in your
`settings.py` while developing locally without HTTPS connections enabled. Without this setting, the
Google One Tap iframe will not load correctly due to a missing Referrer header.

```
    SECURE_REFERRER_POLICY = "no-referrer-when-downgrade"
```

#### Configure the Rownd Hub (required)

Rownd authentication requires a small code snippet to be embedded within your
app, present on all HTML pages. Setup for the Hub/snippet itself is outside the
scope of this document, but you can find the relevant setup guides for either
[single page apps](https://docs.rownd.io/rownd/sdk-reference/web/react-next.js)
or
[traditional web apps via vanilla js](https://docs.rownd.io/rownd/sdk-reference/web/javascript-browser).

Use our SDKs to embed the Hub/snippet in your SPA or use the vanilla JS SDK to
add the snippet in your main Django template HTML.

Now that everything is set up, you can add Rownd authentication to your APIs or
views.

### Usage

The Rownd Django SDK provides support for both "traditional" Django apps where
you have an authentication session that follows a user across page loads, as
well as "single-page" (SPA) Django apps using frameworks like React, Vue, etc.

#### Single-page apps (SPA) / API-based

When using an SPA framework like React, Vue, or similar, you'll likely want to
leverage the specific Rownd SDK for those frameworks. You can find a list of
supported frameworks in
[our documentation](https://docs.rownd.io/rownd/sdk-reference/web).

Typically, an SPA will use an API-driven request/response flow which makes
typical sessions unnecessary (though Rownd supports them if you need them). We
highly recommend the
[Django REST framework](https://www.django-rest-framework.org/) for this
purpose. Rownd provides plug-and-play support for the REST framework's
authentication API.

Here's an example of how you might configure an API to leverage Rownd's
authenticator, given the installation instructions above:

```py theme={null}
from rownd_django.auth.backend import RowndApiAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView

class ExampleView(APIView):
    authentication_classes = [RowndApiAuthentication]
    permission_classes = [IsAuthenticated]

    def get(self, request, format=None):
        content = {
            'user': str(request.user),  # `django.contrib.auth.User` instance.
            'auth': str(request.auth),  # None
        }
        return Response(content)
```

#### Traditional (non-SPA) apps / session-based

In this flow, once a user has been authenticated with the Rownd Hub, the Hub
will make a request to your app's backend to set up a session for the user.

First, ensure your project has session middleware enabled.

```py theme={null}
MIDDLEWARE = [
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    ...
]
```

Next, include the Rownd `session_authenticator` in your `urls.py` file.

```py theme={null}
urlpatterns = [
    ...
    path('rownd/', include('rownd_django.auth.urls', namespace='rownd')),
    ...
]
```

Finally, update your Rownd Hub code snippet to fire post-authenticate and post-sign-out API requests
to the session authenticator we just enabled.

```js theme={null}
<script type="text/javascript">
(function () {
    // Rownd Hub snippet
})();
</script>
<script type="text/javascript">
    function getCookie(name) {
        let cookieValue = null;
        if (document.cookie && document.cookie !== '') {
            const cookies = document.cookie.split(';');
            for (let i = 0; i < cookies.length; i++) {
                const cookie = cookies[i].trim();
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) === (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }

    _rphConfig.push(['setAppKey', '<rownd app key>']);
    _rphConfig.push(['setPostAuthenticationApi', {
        method: 'post',
        url: '/rownd/session_authenticate',
        extra_headers: {
            'X-CSRFToken': getCookie('csrftoken')
        }
    }]);
    _rphConfig.push(['setPostSignOutApi', {
        method: 'post',
        url: '/rownd/session_post_sign_out',
        extra_headers: {
            'X-CSRFToken': getCookie('csrftoken')
        }
    }]);
</script>
```

The session authenticator will establish an authenticated session if one doesn't
already exist and will return a response indicating that the Rownd Hub should
trigger a page refresh. This is usually necessary for your app views to display
the desired authenticated context. In the event that an authenticated session
already exists, the Hub will not trigger further page refreshes.

#### CSRF Protection

By default CSRF protection is disabled on the two sign-in and sign-out routes provided by Rownd. If
you would like to enable it on those endpoints, you must ensure all of your sites views contain the
`csrftoken` cookie and update your settings to enable the CSRF protection. You can find more information
on the `csrftoken` cookie [here](https://docs.djangoproject.com/en/4.2/ref/csrf/).

```python theme={null}
ROWND = {
    'APP_KEY': '<your app key>',
    'APP_SECRET': '<your app secret>',
    'CSRF_PROTECT_ROUTES': True
}
```
