This is the point between the
navigator.id.request
and the
navigator.id.watch
callback for
onlogin
—we send the assertion via POST to the login URL on our site,
which I’ve put at
accounts/login
.
On the server, we now have the job of verifying the assertion: is it really proof that the
user owns that email address? Our server can check, because Google has signed part of
the assertion with its public key. We can either write code to do the crypto for this step
ourselves, or we can use a public service from Mozilla to do it for us.
Yes, letting Mozilla do it for us totally defeats the whole privacy point,
but it’s the
principle
. We could do it ourselves if we wanted to. It’s left
as an exercise for the reader! There are more details on the
Mozilla site ,including all the clever public key crypto that keeps Google from
knowing what site you want to log in to, but also stops replay at‐
tacks and so on. Smart.
The Server Side: Custom Authentication
Next we prep an app for our accounts stuff:
$
python3 manage.py startapp accounts
Here’s the view that handles the POST to
accounts/login
:
accounts/views.py.
import
sys
from
django.contrib.auth
import
authenticate
from
django.contrib.auth
import
login
as
auth_login
from
django.shortcuts
import
redirect
def
login
(
request
):
(
'login view'
,
file
=
sys
.
stderr
)
# user = PersonaAuthenticationBackend().authenticate(request.POST['assertion'])
user
=
authenticate
(
assertion
=
request
.
POST
[
'assertion'
])
if
user
is
not
None
:
auth_login
(
request
,
user
)
return
redirect
(
'/'
)
You can see that it’s clearly “spike” code from things like the commented-out line, evi‐
dence of an early experiment that failed.
Here’s the
authenticate
function, which is implemented as a custom Django “authen‐
tication backend”. (We could have done it inline in the view, but using a backend is the
Django recommended way. It would let us reuse the authentication system in the admin
site, for example.)
Exploratory Coding, aka “Spiking”
|
245