A passworldess plugin for Django Rest Framework authentication package
Project description
⛔️ ALPHA -- WORK IN PROGRESS
jwt drf passwordless
A Passwordless login add-on for Django Rest Framework authentication. Built with django-sms
, django-phonenumber-field
and djangorestframework-simplejwt
with complete statelessness in mind.
Great Thanks
This project is a fork of Sergioisidoro's djoser-passwordless
project, I have mostly just modified and customized this to be more in line with my own needs and preferences. Which include statelessness, independence of other authentication packages, and a more flexible and configurable approach to the token generation and validation.
🔑 Before you start!
Please consider your risk and threat landscape before adopting this library.
Authentication is always a trade-off of usability and security. This library has been built to give you the power to adjust those trade-offs as much as possible, and made an attempt to give you a reasonable set of defaults, but it's up to you to make those decisions. Please consider the following risks bellow.
TODO
- recaptcha verification
- webauthn support
- better documentation
Installation
pip install jwt_drf_passwordless
settings.py
INSTALLED_APPS = (
...
"jwt_drf_passwordless",
...
)
...
jwt_drf_passwordless = {
"ALLOWED_PASSWORDLESS_METHODS": ["EMAIL", "MOBILE"]
}
Remember to set the settings for django-sms
and django-phonenumber-field
if you are using mobile token requests
urlpatterns = (
...
re_path(r"^passwordless/", include("jwt_drf_passwordless.urls")),
...
)
🕵️ Risks
Brute force
Although token requests are throttled by default, and token lifetime is limited, if you know a user email/phone it is possible to continuously request tokens (the default throttle is 1 minute), and try to brute force that token during the token lifetime (10 minutes).
Mitigations
-
Set
INCORRECT_SHORT_TOKEN_REDEEMS_TOKEN
toTrue
, so that any attempts at redeeming a token from an account will count as a user (MAX_TOKEN_USES
is default set to 1) - Tradeoff is that if a user is being a victim of brute force attack, they will not be able to login with passwordless tokens, since it's likely the attacker will exhaust the token uses with failed attempts -
Set
DECORATORS.token_redeem_rate_limit_decorator
orDECORATORS.token_request_rate_limit_decorator
with your choice of request throttling library. - Tradeoff is that if there is an attacker hitting your service, you might prevent any user from logging in because someone is hitting this endpoint, so beware how you implement it. Note that because request limiting usually requires a key value db like redis, it is explicitly left out of this project to reduce it's dependencies and configuration needs.
Features
- International phone number validation and standardization (expects db phone numbers to be in same format)
- Basic throttling
- Stateless JWT tokens by default
- Short (for SMS) and long tokens for magic links
- Configurable serializers, permissions and decorators.
URLs and Examples:
Available URLS
request/email/
request/mobile
exchange/email/
exchange/mobile/
Requesting a token
curl --request POST \
--url http://localhost:8000/passwordless/request/email/ \
--data '{
"email": "sergioisidoro@example.com"
}'
Response
{
"detail": "A token has been sent to you"
}
Exchanging a one time token for a auth token
curl --request POST \
--url http://localhost:8000/passwordless/exchange/ \
--data '{
"email": "sergioisidoro@example.com"
"token": "902488"
}'
{
"refresh": "3b8e6a2aed0435f95495e728b0fb41d0367a872d",
"access": "3b8e6a2aed0435f95495e728b0fb41d0367a872d"
}
Config
Basic configuration
ALLOWED_PASSWORDLESS_METHODS
(default=["email"]) - Which methods can be used to request a token? (Valid -["email", "mobile"]
)EMAIL_FIELD_NAME
(default="email") - Name of the user field that holds the email infoMOBILE_FIELD_NAME
(default="phone_number") - Name of the user field that holds phone number infoSHORT_TOKEN_LENGTH
(default=6) - The length of the short tokensLONG_TOKEN_LENGTH
(default=64) - The length of the tokens that can redeemed standalone (without the original request data)SHORT_TOKEN_CHARS
(default="0123456789") - The characters to be used when generating the short tokenLONG_TOKEN_CHARS
(default="abcdefghijklmnopqrstuvwxyz0123456789") - Tokens used to generate the long tokenTOKEN_LIFETIME
(default=600) - Number of seconds the token is validMAX_TOKEN_USES
(default=1) - How many times a token can be used - This can be adjusted because some email clients try to follow links, and might accidentally use tokens.TOKEN_REQUEST_THROTTLE_SECONDS
- (default=60) - How many seconds to wait before allowing a new token to be issued for a particular userALLOW_ADMIN_AUTHENTICATION
(default=False) - Allow admin users to login without password (checksis_admin
andis_staff
from DjangoAbstractUser
)REGISTER_NONEXISTENT_USERS
(default=False) - Register users who do not have an account and request a passwordless login token?REGISTRATION_SETS_UNUSABLE_PASSWORD
(Default=True) - When unusable password is set, users cannot reset passwords via the normal Django flows. This means users registered via passwordless cannot login through password.INCORRECT_SHORT_TOKEN_REDEEMS_TOKEN
(default=False) - Should incorrect short token auth attempts count to the uses of a token? When set to true, together withMAX_TOKEN_USES
to 1, this means a token has only one shot at being used.PASSWORDLESS_EMAIL_LOGIN_URL
(default=None) - URL template for the link redeeming the standalone link: egmy-app://page/{token}
Advanced configuration
Credits
This package was created with Cookiecutter_ and the audreyr/cookiecutter-pypackage
_ project template.
- Aaronn's
django-rest-framework-passwordless
project https://github.com/aaronn/django-rest-framework-passwordless - Cookiecutter: https://github.com/audreyr/cookiecutter
audreyr/cookiecutter-pypackage
: https://github.com/audreyr/cookiecutter-pypackage
License
- Free software: MIT license
- Do no harm
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file jwt_drf_passwordless-0.1.4.tar.gz
.
File metadata
- Download URL: jwt_drf_passwordless-0.1.4.tar.gz
- Upload date:
- Size: 14.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 64313106130c9b158f23c303f13ec7e79c7cd80f6684add1995fa2e9a26c14ae |
|
MD5 | 42213572e0072809b1b3a115aa6718d8 |
|
BLAKE2b-256 | e4ee5db1bead54a34c51e063c9a319bc57b8807ba3316e80d1ceb6a9ca552e7f |
File details
Details for the file jwt_drf_passwordless-0.1.4-py3-none-any.whl
.
File metadata
- Download URL: jwt_drf_passwordless-0.1.4-py3-none-any.whl
- Upload date:
- Size: 18.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/5.1.1 CPython/3.12.5
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 41fd2d63a368936e885df7eca0df8874f74171359eb31e9e325ba4c0bcbb56a9 |
|
MD5 | 0f22abac120a1c4ead52fc82414f1b4f |
|
BLAKE2b-256 | 7287af9eb5fd6b4a622d4b9897e301c61fdf42ebd115ea8a83c91ab8cd8bb4d5 |