Repository URL to install this package:
|
Version:
0.3.2+sf4 ▾
|
| siwe_auth |
| LICENSE.txt |
| README.md |
| pyproject.toml |
| setup.py |
| PKG-INFO |
This app provides four key features for new or existing Django projects.
Below is the included example application that authenticates with an Ethereum address and utilizes on-chain attributes to authorize access to various notepads.
With the included example applications, you can test out Sign-In with Ethereum along with using and creating custom groups. To get an example application up and running follow these steps.
Requirements for developing and running examples apps:
npm --prefix examples/notepad/frontend install examples/notepad/frontend
npm run --prefix examples/notepad/frontend build
poetry install
export SIWE_AUTH_PROVIDER="https://mainnet.infura.io/v3/..." # Any provider works
# Create Django migrations poetry run examples/notepad/manage.py makemigrations # Apply Django migrations poetry run examples/notepad/manage.py migrate
poetry run examples/notepad/manage.py runserver
https://localhost:8000If you make an update to the frontend directory or siwe submodule, rebuild bundle.js:
cd examples/notepad/frontend \ npm install \ npm run build
This project is highly configurable and modular allowing for applications to be as simple or complex as required. Authentication and authorization can be completely replaced or supplemented depending upon the use case. See scenario docs for detailed tutorials.
Requirements for using django-siwe-auth in a Django application:
pip install django-siwe-auth
siwe_auth.apps.SiweAuthConfig to INSTALLED_APPS in your project's settings.py
INSTALLED_APPS = [ ... "siwe_auth.apps.SiweAuthConfig", # Adds django-siwe-auth "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", ]
settings.py (same files as previous step). For more information, see the Configuring Your Project section
from siwe_auth.custom_groups.erc721 import ERC721OwnerManager ... # Django Sign-In with Ethereum Auth Settings AUTH_USER_MODEL = "siwe_auth.Wallet" AUTHENTICATION_BACKENDS = ["siwe_auth.backend.SiweBackend"] LOGIN_URL = "/" SESSION_COOKIE_AGE = 3 * 60 * 60 CREATE_GROUPS_ON_AUTHN = False # defaults to False CREATE_ENS_PROFILE_ON_AUTHN = True # defaults to True CUSTOM_GROUPS = [ ('ens_owners', ERC721OwnerManager(config={'contract': '0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85'})), ('bayc_owners', ERC721OwnerManager(config={'contract': '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D'})), ('shib_owners', ERC20OwnerManager(config={'contract': '0x95ad61b0a150d79219dcf64e1e6cc01f0b64c4ce'})), ] # See "Group Plugins" section PROVIDER = os.environ.get("SIWE_AUTH_PROVIDER", "https://mainnet.infura.io/v3/...") ...
api/auth/ endpoint to your project's urls.py
urlpatterns = [ path("admin/", admin.site.urls), path("api/auth/", include("siwe_auth.urls")), ... ]
manage.py makemigrations and manage.py migrate to create custom user modelFor more examples, please refer to the Documentation
Projects that use this app will interact via these endpoints for authentication. Tools for authorization are provided but not enforced via any endpoints.
Method:
POST
URL Params
None
Data Params
Required:
{"message": **SIWE message dict or formatted string**, "signature": **user signature of prior message**}
Success Response:
{"success": True, "message": "Successful login."}Error Response:
{"success": False, "message": "Wallet disabled."}OR
{"success": False, "message": "Invalid login."}OR
{"message": "Too many requests. Slow down."}Sample Call:
const res = await fetch(`/api/auth/login`, { method: "POST", headers: { 'Content-Type': 'application/json', 'X-CSRFToken': document.getElementsByName('csrfmiddlewaretoken')[0].value, }, body: JSON.stringify({ message, signature }), credentials: 'include' });
Method:
POST
URL Params
None
Data Params
None
Success Response:
/Error Response:
{"message": "Too many requests. Slow down."}Sample Call:
const res = await fetch(`/api/auth/logout`, { method: "POST", headers: { 'Content-Type': 'application/json', 'X-CSRFToken': document.getElementsByName('csrfmiddlewaretoken')[0].value, }, credentials: 'include' });
Method:
GET
URL Params
None
Data Params
None
Success Response:
{"nonce": **one-time use nonce**}Error Response:
{"message": "Too many requests. Slow down."}Sample Call:
const res = await fetch(`/api/auth/nonce`, { credentials: 'include', headers: { 'X-CSRFToken': document.getElementsByName('csrfmiddlewaretoken')[0].value, }, });
# in settings.py AUTH_USER_MODEL = "siwe_auth.Wallet" # required for siwe as the default authentication AUTHENTICATION_BACKENDS = ["siwe_auth.backend.SiweBackend"] # required for siwe as the default authentication LOGIN_URL = "/" # optional, django's default is "/accounts/login/" SESSION_COOKIE_AGE = 3 * 60 * 60 # Age of cookie, in seconds. Optional, django's default is weeks.
# in settings.py CREATE_GROUPS_ON_AUTHN = True # optional, default is False CREATE_ENS_PROFILE_ON_AUTHN = True # optional, default is True CUSTOM_GROUPS = [] # optional, see "Adding a Group" below # Set environment variable SIWE_AUTH_PROVIDER for Web3.py # - Required if CREATE_GROUPS_ON_AUTHN or CREATE_ENS_PROFILE_ON_AUTHN are True. Optional otherwise. # Any ethereum API key (infura or alchemy) will work. PROVIDER = os.environ.get("SIWE_AUTH_PROVIDER", "https://mainnet.infura.io/v3/...")
In order to login to the django admin page with siwe-auth, we need to override the login template.
# in your app's admin.py, add the following line admin.site.login_template = 'siwe_auth/login.html'
A group plugin allows you to define your own group whose membership is defined by the output of a membership function. Some examples of what the membership function may check for include but are not limited to: NFT ownership, ERC-20 token ownership, ENS data, etc.
All group plugins must implement the GroupManager class. This includes a function called is_member that is called to determine group membership when a user authenticates with the server.
from abc import ABC, abstractmethod class GroupManager(ABC): @abstractmethod def __init__(self, config: dict): pass @abstractmethod def is_member(self, wallet: object) -> bool: pass
A custom group is defined by a tuple consisting of a name (string), MemberManager implementation.
The GroupManager's config can be used for anything, but some likely usecases are defining contract addresses or address include/exclude lists.
In your project's settings.py, append your group to the CUSTOM_GROUPS list added in the installation steps.
Suppose we want to have only one group for BAYC (ERC721 NFT) owners and another group for LPT (ERC20 Token) owners. Our list would then look like:
from siwe_auth.custom_groups.erc721 import ERC721OwnerManager from siwe_auth.custom_groups.erc20 import ERC20OwnerManager ... CUSTOM_GROUPS=[ ('bayc_owners', ERC721OwnerManager(config={'contract': '0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d'})), ('lpt_owners', ERC20OwnerManager(config={'contract': '0x58b6a8a3302369daec383334672404ee733ab239'})), ]
Examples:
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)Distributed under the MIT License. See LICENSE.txt for more information.
payton - @paytongarland - paytongarland.eth
Project Link: https://github.com/payton/django-siwe-auth
This django auth library has not yet undergone a formal security audit. We welcome continued feedback on the usability, architecture, and security of this implementation.