Package: django-sceneid
django-sceneidSceneIDauthentication for DjangoHow it worksIt's assumed that your website has an existing login system, based onDjango's authentication framework. SceneID does not replace it - the ability to log in via SceneID will be offered as an alternative alongside the standard login form. The existing User model will continue to be used, regardless of whether a user logs in through SceneID or a regular username / password.The 'Sign in with SceneID' link will authenticate the user against SceneID. If the SceneID account is already associated with a user account on the website (as stored in the database under the sceneid.SceneID model), that user is immediately logged in and your website can refer torequest.useras normal. Otherwise, the user is redirected to a 'connect' view, prompting them to either log in with an existing username / password, or register a new account (in which case they'll be prompted for a username and other required fields, but not password). In both cases, the resulting user account will be linked to the SceneID account so that they can log in immediately next time.Demo site (including much of the configuration and customisation described below) -https://github.com/demozoo/django-sceneid-demositeInstallationdjango-sceneid is compatible with Django 3.x and 4.x. To install:pipinstalldjango-sceneidAdd'sceneid'to your project'sINSTALLED_APPS, then run./manage.py migrate.In your project's top-level URL config, include the URLconfsceneid.urls:fromdjango.urlsimportinclude,pathurlpatterns=[# ...path('account/sceneid/',include('sceneid.urls')),# ...]At this point you'll need toobtain an API key from scene.org. They'll want to know your redirect URI, which is the path you used above withlogin/appended; for examplehttps://demosite.example.com/account/sceneid/login/. Once you have this, add the following settings to your project's settings file:# The client ID you received from scene.orgSCENEID_CLIENT_ID='demosite'# The client secret you received from scene.orgSCENEID_CLIENT_SECRET='supersecretclientsecret'# The root URL of your website, without a trailing slashBASE_URL='https://demosite.example.com'# Where to redirect to after login (defaults to /accounts/profile/)LOGIN_REDIRECT_URL='/'Integrating into your siteThe simplest way to add a 'sign in with SceneID' button to your site is to add thesceneid_login_button_smallorsceneid_login_button_largetemplate tag in a suitable place on your template:{%loadsceneid_tags%}{# must be at the top of your template #}{%ifnotrequest.user.is_authenticated%}{%sceneid_login_button_large%}{%endif%}This will output a button linking to the login view, with a 'next' parameter that will redirect back to the current page after login (unless the current page is a POST request, in which case this will be omitted). To override this, pass anext_urlparameter to the tag - this can be the desired redirect URL, or False to disable it entirely.{%sceneid_login_button_largenext_url='/some/other/path/'%}{%sceneid_login_button_largenext_url=False%}If you don't want to use the button images, thesceneid_auth_urltag outputs just the URL, to be inserted into a link of your choice. This tag also accepts anext_urlparameter, as well as supporting theas varsyntax to write the result to a variable:{%sceneid_auth_urlnext_url='/some/other/path/'asauth_url%}<ahref="{{auth_url}}">Sign in with SceneID</a>CustomisationAt minimum, you'll probably want to customise the template for the 'connect' view to match your site styling. The quick-and-dirty way to do this is to create a template with the pathsceneid/connect.htmlwithin one of your apps, and ensuring that template takes precedence over the default one by placing that app's entry above'sceneid'inINSTALLED_APPS. This template receives the following context variables:user_data- the dictionary of user datareturned from SceneID, consisting ofid,first_name,last_nameanddisplay_namelogin_form- aDjango form objectfor the login form, to be POSTed to{% url 'sceneid:connect_old' %}register_form- aDjango form objectfor the registration form, to be POSTed to{% url 'sceneid:connect_new' %}For more control over customisations, you canoverride the AppConfigfor thesceneidapp. Within your project-level configuration folder (i.e. the one containing thesettingsandurlssubmodules), add the following toapps.py:fromsceneid.appsimportSceneIDConfigclassDemositeSceneIDConfig(SceneIDConfig):connect_template_name='accounts/connect.html'Then replace the'sceneid'entry inINSTALLED_APPSwith the dotted path to the AppConfig class:INSTALLED_APPS=[# ...'demosite.apps.DemositeSceneIDConfig',# ...]The template path specified inconnect_template_namewill then be used for the 'connect' view.Custom formsThe form classes used for the login and registration forms are also configurable from the AppConfig class:connect_login_form_class(default:'django.contrib.auth.forms.AuthenticationForm')connect_register_form_class(default:'sceneid.forms.UserCreationForm')In particular, the providedUserCreationFormcan be subclassed to add extra fields to the data collected on account creation. For example, to include fields for first name and last name (which will then populate the corresponding fields on the standard Django user model):# accounts/forms.pyfromsceneid.formsimportUserCreationFormasBaseUserCreationFormclassSceneIDUserCreationForm(BaseUserCreationForm):classMeta(BaseUserCreationForm.Meta):fields=('username','first_name','last_name')# demosite/apps.pyfromsceneid.appsimportSceneIDConfigclassDemositeSceneIDConfig(SceneIDConfig):connect_template_name='accounts/connect.html'connect_register_form_class='accounts.forms.SceneIDUserCreationForm'The baseUserCreationFormclass recognises the field namesfirst_nameandlast_namewhere present and pre-populates these from the SceneID data, in addition to pre-populating theusernamefield with a cleaned version of the SceneID display name.Using django-sceneid witha custom User modelis currently untested. The baseUserCreationFormassumes the presence of a'username'field and will need to be customised accordingly if this is not the case (e.g. if your site uses email as a user's identifier instead), but all other functionality (including the login form) should work unchanged.