# Django-JWT-Extended
![Python versions](https://img.shields.io/pypi/pyversions/django-jwt-extended) ![License](https://img.shields.io/badge/license-MIT-green) ![Release](https://img.shields.io/pypi/v/django-jwt-extended)
Implement JWT authentication with Django quickly and easily!
**Inspired by [flask-jwt-extended](https://github.com/vimalloc/flask-jwt-extended).**
# Installation
**Pip**: `pip install django-jwt-extended`
After that, add `django_jwt_extended` to `INSTALLED_APPS` settings.
```
INSTALLED_APPS = [
...
'django_jwt_extended',
]
```
# Get Started
`django-jwt-extended` makes it easy and simple to create authentication feature.
## Startup your project
```shell
$ pip install django
$ pip install django-jwt-extended
$ django-admin startproject example .
$ python manage.py migrate
$ python manage.py createsuperuser
```
## Edit your views
```python
# views.py
from django.http import JsonResponse
from django_jwt_extended import jwt_required
from django_jwt_extended import create_access_token
from django_jwt_extended import get_jwt_identity
def login(request):
"""Create JWT Token API"""
return JsonResponse({
"access_token": create_access_token(identity="iml"),
})
@jwt_required()
def user(request):
"""JWT Authentication API"""
identity = get_jwt_identity(request) # "iml"
return JsonResponse({'id': identity,})
```
# Advanced Usage
This section goes into more detail about django-jwt-extended.
## Return with refresh token
If you want to return not only the access token but also the refresh token, you can use it as follows. `Identity` is input as an argument to generate tokens.
This `Identity` can contain any object that **can be serialized as json**, and is stored in "sub" of JWT Schema.
```python
from django_jwt_extended import create_access_token
from django_jwt_extended import create_refresh_token
# Login and issue tokens
def login(request):
return JsonResponse({
"access_token": create_access_token("iml"),
'refresh_token': create_refresh_token('iml'),
})
```
## Refresh Token Authentication
When you want to perform authentication through refresh token, Set the refresh argument to `True` as shown below.
```python
# Refresh tokens
@jwt_required(refresh=True) # refresh token check
def refresh(request):
identity = get_jwt_identity(request)
return JsonResponse({
"access_token": create_access_token(identity),
'refresh_token': create_refresh_token(identity),
})
```
## Parse JWT Payload
There are two ways to get the contents of jwt token. These are `get_jwt_identity` and `get_jwt`.
`get_jwt_identity` returns the identity value given when creating the token as it is.
`get_jwt` returns the full payload that decoded the jwt token.
```python
# Authentication access token
@jwt_required()
def user(request):
identity = get_jwt_identity(request)
payload = get_jwt(request)
return JsonResponse({
'id': identity,
'raw_jwt': payload,
})
```
## Optional Authentication
If the optional argument is `True`, the verification step is passed even if the corresponding token does not exist. However, in this case, even if **identity or jwt payload** is called, `None` is returned.
```python
# Optional Login example
@jwt_required(optional=True)
def user_optional(request):
identity = get_jwt_identity(request)
return JsonResponse({'id': identity})
```
## Custom Decorator Pattern
If it is cumbersome to implement the `jwt_required` logic repeatedly every time, you can implement a custom decorator as shown below. This is only an example, and more various methods may exist.
```python
# Authentication access token with Decorator
def login_required(func):
@jwt_required()
def wrapper(request, **path):
identity = get_jwt_identity(request)
request.META['logined_identity'] = identity # before request
response = func(request, **path)
request.META.pop('logined_identity') # after request
return response
return wrapper
@login_required
def decorator_user(request):
identity = request.META['logined_identity']
payload = get_jwt(request)
return JsonResponse({
'id': identity,
'raw_jwt': payload,
})
```
# Configuration
Even if you don't configure anything, your app works.
But in `settings.py` in your app, You can customize your app through the following settings.
Here's a good sample.
```python
# settings.py
SECRET_KEY = "super-secret"
JWT_CONFIG = {
'ALGORITHM': 'HS256',
'LOCATION': ['headers'],
'ACCESS_TOKEN_EXPIRES': timedelta(days=2),
'REFRESH_TOKEN_EXPIRES': timedelta(days=30),
'JWT_NOT_FOUND_MSG': {'msg': "can't find JWT token."}
}
...
```
## SECRET_KEY
This is the secret key setting that Django supports by default.
`Django-jwt-extended` also, the key is used when encoding/decoding JWT.
## JWT_CONFIG
`JWT_CONFIG` is a setting added for `django_jwt_extended`.
Additional settings can be added as follows in the form of a dictionary.
### ALGORITHM
`ALGORITHM: "HS256" `
- Default: `HS256`
- Allowed_values: `HS256`
Select the encode/decode algorithm to issue tokens. (Currently only '**HS256**' is supported)
### LOCATION
`LOCATION: ["headers", ...]`
- default: `["headers"]`
- allowed_values: `headers`, `cookies`
This setting determines where to collect the Tokens. The thing to note is that **input is received as a list, not as a single string**. You can pass in a list to check more then one location, for example `["headers", "cookies"]`. The order of the list sets the precedence of where JWTs will be looked for.
- **headers**
For headers, the header name is fixed to **"Authorization"**, and the token format is **"Bearer [token]"**.
- **cookies**
In the cookie, you can directly specify **the cookie name for the access token** and **the cookie name for the refresh token.**
### ACCESS_TOKEN_COOKIE_NAME
`ACCESS_TOKEN_COOKIE_NAME: access_token`
- Default: `access_token`
- Allowed_types: `string`
The name of the cookie that will store the access token.
### REFRESH_TOKEN_COOKIE_NAME
`REFRESH_TOKEN_COOKIE_NAME: refresh_token`
- Default: `refresh_token`
- Allowed_types: `string`
The name of the cookie that will store the refresh token.
### ACCESS_TOKEN_EXPIRES
`ACCESS_TOKEN_EXPIRES: 60 * 24 * 2 # 2days`
- Default: `60 * 24 * 2`
- Allowed_types: `integer`, `datetime.timedelta`
How long an access token should be valid before it expires. This can be a a number of seconds (`Integer`).
### REFRESH_TOKEN_EXPIRES
`REFRESH_TOKEN_EXPIRES: 60 * 24 * 30 # 1month`
- Default: `60 * 24 * 30`
- Allowed_types: `integer`, `datetime.timedelta`
How long a refresh token should be valid before it expires. This can be a number of seconds (`Integer`).
Raw data
{
"_id": null,
"home_page": "https://github.com/iml1111/django-jwt-extended",
"name": "django-jwt-extended",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "django jwt extended",
"author": "IML",
"author_email": "shin10256@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/97/c7/5d3928b0a8ef6fbbecad2e401ff42a809daae36ffad1e3a5fcf6aa52a0b8/django-jwt-extended-2.0.0.tar.gz",
"platform": "any",
"description": "# Django-JWT-Extended\n\n![Python versions](https://img.shields.io/pypi/pyversions/django-jwt-extended) ![License](https://img.shields.io/badge/license-MIT-green) ![Release](https://img.shields.io/pypi/v/django-jwt-extended)\n\nImplement JWT authentication with Django quickly and easily!\n**Inspired by [flask-jwt-extended](https://github.com/vimalloc/flask-jwt-extended).**\n\n\n\n# Installation\n\n**Pip**: `pip install django-jwt-extended`\n\nAfter that, add `django_jwt_extended` to `INSTALLED_APPS` settings.\n\n```\nINSTALLED_APPS = [\n ...\n 'django_jwt_extended',\n]\n```\n\n\n\n# Get Started\n\n`django-jwt-extended` makes it easy and simple to create authentication feature.\n\n## Startup your project\n\n```shell\n$ pip install django\n$ pip install django-jwt-extended\n$ django-admin startproject example .\n$ python manage.py migrate\n$ python manage.py createsuperuser\n```\n\n## Edit your views\n\n```python\n# views.py\nfrom django.http import JsonResponse\nfrom django_jwt_extended import jwt_required\nfrom django_jwt_extended import create_access_token\nfrom django_jwt_extended import get_jwt_identity\n\ndef login(request):\n \"\"\"Create JWT Token API\"\"\"\n return JsonResponse({\n \"access_token\": create_access_token(identity=\"iml\"),\n })\n\n@jwt_required()\ndef user(request):\n \"\"\"JWT Authentication API\"\"\"\n identity = get_jwt_identity(request) # \"iml\"\n return JsonResponse({'id': identity,})\n```\n\n\n\n# Advanced Usage\n\nThis section goes into more detail about django-jwt-extended.\n\n## Return with refresh token\n\nIf you want to return not only the access token but also the refresh token, you can use it as follows. `Identity` is input as an argument to generate tokens. \n\nThis `Identity` can contain any object that **can be serialized as json**, and is stored in \"sub\" of JWT Schema.\n\n```python\nfrom django_jwt_extended import create_access_token\nfrom django_jwt_extended import create_refresh_token\n\n# Login and issue tokens\ndef login(request):\n return JsonResponse({\n \"access_token\": create_access_token(\"iml\"),\n 'refresh_token': create_refresh_token('iml'),\n })\n```\n\n## Refresh Token Authentication\n\nWhen you want to perform authentication through refresh token, Set the refresh argument to `True` as shown below.\n\n```python\n# Refresh tokens\n@jwt_required(refresh=True) # refresh token check\ndef refresh(request):\n identity = get_jwt_identity(request)\n return JsonResponse({\n \"access_token\": create_access_token(identity),\n 'refresh_token': create_refresh_token(identity),\n })\n```\n\n## Parse JWT Payload\n\nThere are two ways to get the contents of jwt token. These are `get_jwt_identity` and `get_jwt`. \n\n `get_jwt_identity` returns the identity value given when creating the token as it is.\n\n`get_jwt` returns the full payload that decoded the jwt token.\n\n```python\n# Authentication access token\n@jwt_required()\ndef user(request):\n identity = get_jwt_identity(request)\n payload = get_jwt(request)\n return JsonResponse({\n 'id': identity,\n 'raw_jwt': payload,\n })\n```\n\n## Optional Authentication\n\n If the optional argument is `True`, the verification step is passed even if the corresponding token does not exist. However, in this case, even if **identity or jwt payload** is called, `None` is returned.\n\n```python\n# Optional Login example\n@jwt_required(optional=True)\ndef user_optional(request):\n identity = get_jwt_identity(request)\n return JsonResponse({'id': identity})\n```\n\n## Custom Decorator Pattern\n\nIf it is cumbersome to implement the `jwt_required` logic repeatedly every time, you can implement a custom decorator as shown below. This is only an example, and more various methods may exist.\n\n```python\n# Authentication access token with Decorator\ndef login_required(func):\n @jwt_required()\n def wrapper(request, **path):\n identity = get_jwt_identity(request)\n request.META['logined_identity'] = identity # before request\n response = func(request, **path)\n request.META.pop('logined_identity') # after request\n return response\n return wrapper\n\n@login_required\ndef decorator_user(request):\n identity = request.META['logined_identity']\n payload = get_jwt(request)\n return JsonResponse({\n 'id': identity,\n 'raw_jwt': payload,\n })\n```\n\n\n\n# Configuration\n\nEven if you don't configure anything, your app works.\n\nBut in `settings.py` in your app, You can customize your app through the following settings. \n\nHere's a good sample.\n\n```python\n# settings.py\n\nSECRET_KEY = \"super-secret\"\n\nJWT_CONFIG = {\n 'ALGORITHM': 'HS256',\n 'LOCATION': ['headers'],\n 'ACCESS_TOKEN_EXPIRES': timedelta(days=2),\n 'REFRESH_TOKEN_EXPIRES': timedelta(days=30),\n 'JWT_NOT_FOUND_MSG': {'msg': \"can't find JWT token.\"}\n}\n...\n```\n\n\n\n## SECRET_KEY\n\nThis is the secret key setting that Django supports by default. \n\n`Django-jwt-extended` also, the key is used when encoding/decoding JWT.\n\n## JWT_CONFIG\n\n`JWT_CONFIG` is a setting added for `django_jwt_extended`. \n\nAdditional settings can be added as follows in the form of a dictionary.\n\n### ALGORITHM\n\n`ALGORITHM: \"HS256\" `\n\n- Default: `HS256`\n- Allowed_values: `HS256`\n\nSelect the encode/decode algorithm to issue tokens. (Currently only '**HS256**' is supported)\n\n### LOCATION\n\n`LOCATION: [\"headers\", ...]`\n\n- default: `[\"headers\"]`\n- allowed_values: `headers`, `cookies`\n\nThis setting determines where to collect the Tokens. The thing to note is that **input is received as a list, not as a single string**. You can pass in a list to check more then one location, for example `[\"headers\", \"cookies\"]`. The order of the list sets the precedence of where JWTs will be looked for.\n\n- **headers**\n\nFor headers, the header name is fixed to **\"Authorization\"**, and the token format is **\"Bearer [token]\"**.\n\n- **cookies**\n\n In the cookie, you can directly specify **the cookie name for the access token** and **the cookie name for the refresh token.**\n\n### ACCESS_TOKEN_COOKIE_NAME\n\n`ACCESS_TOKEN_COOKIE_NAME: access_token`\n\n- Default: `access_token`\n- Allowed_types: `string`\n\nThe name of the cookie that will store the access token.\n\n### REFRESH_TOKEN_COOKIE_NAME\n\n`REFRESH_TOKEN_COOKIE_NAME: refresh_token`\n\n- Default: `refresh_token`\n- Allowed_types: `string`\n\nThe name of the cookie that will store the refresh token.\n\n### ACCESS_TOKEN_EXPIRES\n\n`ACCESS_TOKEN_EXPIRES: 60 * 24 * 2 # 2days`\n\n- Default: `60 * 24 * 2`\n- Allowed_types: `integer`, `datetime.timedelta`\n\nHow long an access token should be valid before it expires. This can be a a number of seconds (`Integer`).\n\n### REFRESH_TOKEN_EXPIRES\n\n`REFRESH_TOKEN_EXPIRES: 60 * 24 * 30 # 1month`\n\n- Default: `60 * 24 * 30`\n- Allowed_types: `integer`, `datetime.timedelta`\n\nHow long a refresh token should be valid before it expires. This can be a number of seconds (`Integer`).\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "An open source Django extension that provides Simple JWT Authentication.",
"version": "2.0.0",
"project_urls": {
"Homepage": "https://github.com/iml1111/django-jwt-extended"
},
"split_keywords": [
"django",
"jwt",
"extended"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c045a2c1221a308c468941d4d72f4e1bdf56e575f3e71a078cb3056904d888c2",
"md5": "59ffc2c9491a6ebb4cf5d0e1e0f0d8b3",
"sha256": "9273b07b61338a22bdd8ca913a20e468ddb2c90713bdfa9d2c6a396af3c7ff68"
},
"downloads": -1,
"filename": "django_jwt_extended-2.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "59ffc2c9491a6ebb4cf5d0e1e0f0d8b3",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 9932,
"upload_time": "2024-10-02T20:51:48",
"upload_time_iso_8601": "2024-10-02T20:51:48.474857Z",
"url": "https://files.pythonhosted.org/packages/c0/45/a2c1221a308c468941d4d72f4e1bdf56e575f3e71a078cb3056904d888c2/django_jwt_extended-2.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "97c75d3928b0a8ef6fbbecad2e401ff42a809daae36ffad1e3a5fcf6aa52a0b8",
"md5": "56feac14a0e368e81058f501d0010d63",
"sha256": "5afd114e53cf4628044d93c498ff465bd9f18911f9c26f6422b6ba214237e489"
},
"downloads": -1,
"filename": "django-jwt-extended-2.0.0.tar.gz",
"has_sig": false,
"md5_digest": "56feac14a0e368e81058f501d0010d63",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 14505,
"upload_time": "2024-10-02T20:51:50",
"upload_time_iso_8601": "2024-10-02T20:51:50.012246Z",
"url": "https://files.pythonhosted.org/packages/97/c7/5d3928b0a8ef6fbbecad2e401ff42a809daae36ffad1e3a5fcf6aa52a0b8/django-jwt-extended-2.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-02 20:51:50",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "iml1111",
"github_project": "django-jwt-extended",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "django-jwt-extended"
}