Metadata-Version: 2.1
Name: dj-ninja-auth
Version: 0.1.2
Summary: A Django app for REST Authentication using Django Ninja
Home-page: https://www.example.com/
Author: Bhargav Singapuri
Author-email: bhsingapuri@gmail.com
License: MIT
Classifier: Environment :: Web Environment
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: Django>=4.2
Requires-Dist: django-ninja-extra>=0.20.0
Requires-Dist: email-validator>=2.1.0.post1
Requires-Dist: PyJWT>=2.8.0
Requires-Dist: cryptography>=41.0.5

# Django Ninja Auth

A one stop shop for all your Django-Ninja Authentication needs.
Supports REST authentication with Sessions, Auth Tokens and JWTs.

Fully Customisable to suit your needs.

## Getting Started

### Installation

<!-- TODO: Only available once published to pypi if at all. -->

```bash
pip install dj-ninja-auth
```

### Setup

#### NinjaAPI

1. Create a `api.py` file in your app directory next to the `settings.py` and `urls.py` files.
2. Add the following lines of code to your `api.py`

    ```python [api.py]
    from ninja_extra import NinjaExtraAPI
    from dj_ninja_auth.controller import NinjaAuthDefaultController

    api = NinjaExtraAPI()
    api.register_controllers(NinjaAuthDefaultController)
    ```

3. Add the following lines to your `urls.py` file

    ```python [urls.py]
    from .api import api

    urlpatterns = [
        path("admin/", admin.site.urls),
        path("", api.urls)
    ]
    ```

This will give you 5 basic endpoints that are not secured and can be called by anyone.
The endpoints are

- `/auth/login`
- `/auth/logout`
- `/auth/password/reset/request`
- `/auth/password/reset/confirm`
- `/auth/password/change`

#### Password Reset Template

Django's default email template requires a `password_reset_confirm` reverse url that is incompatible with Django Ninja's [namespace convention](https://django-ninja.dev/guides/urls/) and will throw [this error](https://github.com/iMerica/dj-rest-auth/issues/494) if not handled properly.
As a workaround, it is required that you provide your own email reset template.
You can place it anywhere in your project as long as you link it in your `settings.py`'s `TEMPLATES` variable.
In my example below, I have put it in the `{$project_root}/templates/` directory.

```python [settings.py]
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [BASE_DIR / "templates"],
        "APP_DIRS": True,
        "OPTIONS": { ... },
    },
]
```

In your `templates` directory, create the following file at `templates/registration/password_reset_email.html` and **minimally** add the following.

```jinja [password_reset_email.html]
{% load i18n %}
{% autoescape off %}

    {% translate "Please go to the following page and choose a new password:" %}

    {% block reset_link %}
        http://{YOUR_DOMAIN_HERE}/{YOUR_FRONTEND_PASSWORD_RESET_ENDPOINT}?uid={{ uid }}&token={{ token }}
    {% endblock %}

{% endautoescape %}
```

**NOTE**: Replace `YOUR_DOMAIN_HERE` and `YOUR_FRONTEND_PASSWORD_RESET_ENDPOINT` with values that correspond to your setup.
The `uid` and `token` variables have to be passed to the backend for verification before the password can be changed.

## Authentication

There are 3 controllers that you can register in your `api.py` file for your application depending on your authentication needs.

### Session

The easiest way to use authentication is to use the Session Authentication.
Note that the `csrf=True` kwarg has to be passed in to allow Django Ninja to pass CSRF cookies for validation.
You will have to [provide your own endpoint](https://django-ninja.dev/reference/csrf/?h=csrf#django-ensure_csrf_cookie-decorator) to get a CSRF cookie from Ninja.

```python [api.py]
from ninja.security import django_auth
from dj_ninja_auth.controller import NinjaAuthDefaultController

api = NinjaExtraAPI(auth=[django_auth], csrf=True)
api.register_controllers(NinjaAuthDefaultController)
```

### Token

Since the `token`s will be stored in the database, you are required to add the `dj_ninja_auth.authtoken` app to your `INSTALLED_APPS` and migrate the database.

```python
from ninja_extra import NinjaExtraAPI
from dj_ninja_auth.authtoken.authentication import AccessTokenAuth
from dj_ninja_auth.authtoken.controller import NinjaAuthTokenController

api = NinjaExtraAPI(auth=[AccessTokenAuth()])
api.register_controllers(NinjaAuthTokenController)
```

### JWT

```python
from ninja_extra import NinjaExtraAPI
from dj_ninja_auth.jwt.authentication import JWTAuth
from dj_ninja_auth.jwt.controller import NinjaAuthJWTController

api = NinjaExtraAPI(auth=[JWTAuth()])
api.register_controllers(NinjaAuthJWTController)
```

The JWT controller provides 2 additional endpoints for tokens.

- `/auth/refresh`
- `/auth/verify`

## Customisation

Every aspect of the the `Schema`s and `Controller`s can be modified to suit your needs.

<!-- TODO: Add Code samples of customisations. -->
