A Gall agent which enables webservers and service providers outside of Urbit to authenticate users, thereby providing a “Login with Urbit ID” experience. %authenticate-with-urbit-id
affords a website running a backend ship to authenticate that a website user does in fact control a particular Urbit ship (thereby supporting hosted ships, L2 ships, and other potential edge cases as well). The authentication protocol is similar to email token-based authentication schemes.
When paired with Urbit Visor, this application will allows users to easily authenticate themselves on classical web2 sites which integrate Authenticate With Urbit ID.
Do note, the website/backend ship running %authenticate-with-urbit-id
must be trusted (meaning run by the website provider, or a trusted 3rd party) and secured on a server with a strong firewall which only allows the website backend (ip) to interact with it. This was chosen to simplify the setup process and reuse the existing networking tech stack so that integration would be easier for implementors with little knowledge of Urbit.
Check out the announcement youtube video for an easy-to-follow summary of Authenticate With Urbit ID. After the youtube video, this deep-dive medium post is recommended as well.
- Boot the host ship.
- On that ship,
|merge %authenticate-with-urbit-id our %base
. - On that ship,
|mount %authenticate-with-urbit-id
. - Outside the ship,
rm -rf ship/authenticate-with-urbit-id/*
. - Outside the ship,
cp -r git-repo/src/* ship/authenticate-with-urbit-id
. - Inside the ship,
|commit %authenticate-with-urbit-id
. - Inside the ship,
|install our %authenticate-with-urbit-id
. You should see a success message and a %no-docket-file-for warning. - Inside the ship,
|public %authenticate-with-urbit-id
(note that this is different because there is no docket file or tile). - From another ship, install at the command line:
|install ~sampel-palnet %authenticate-with-urbit-id
(without a docket file, which we don't need, it currently won't show at the GUI).
%authenticate-with-urbit-id
exposes the following endpoints:
-
/~initiateAuth
-
Input: An Airlock-standard JSON containing the user ship
ship
as a string. -
Output: An Airlock-standard JSON containing the website ship
source
as a string, the user shipship
as a string, and the token for the user as a string. -
Example:
curl --header "Content-Type: application/json" \ --request PUT \ --data '{"ship":"sampel-talled","json":"sampel-palnet"}' \ http://localhost:8080/~initiateAuth
-
-
/~checkAuth
-
Input: A JSON containing the user ship
ship
as a string. -
Output: A JSON containing the requesting website ship
source
as a string, the user shiptarget
as a string, and the status of the user shipstatus
as a string. -
Example:
curl --header "Content-Type: application/json" \ --request PUT \ --data '{"ship":"sampel-talled","json":"sampel-palnet"}' \ http://localhost:8080/~checkAuth
-
In between the website hitting each endpoint, the user's ship should emit a DM containing the secure token to the website ship. %authenticate-with-urbit-id
has subscribed to the %dm-inbox
and will update the authorization status to true
as soon as a DM containing the token has been received.
In the case of multiple initiations, earlier tokens are instantly invalidated.
As soon as a successful check has been made, %authenticate-with-urbit-id
clears the authorization status of the user ship.
This example assumes that the developer is a running a “website ship” ~sampel-talled
and a “user ship” ~sampel-palnet
. (Do note: DMs do not work particularly well between fakezod galaxies.)
-
Start
%authenticate-with-urbit-id
on website ship~sampel-talled
. -
Make a request to
%authenticate-with-urbit-id
on~sampel-talled
to generate a token (typically done via the website backend) for user ship~sampel-palnet
(this token is then returned to the end user from the backend to the frontend, and would be fed through Urbit Visor's API in a DM, as is specified in step 4).curl --header "Content-Type: application/json" \ --request PUT \ --data '{"ship":"sampel-talled","json":"sampel-palnet"}' \ http://localhost:8080/~initiateAuth
-
Check the authentication status of
~sampel-palnet
and confirm that the user ship is not authorized yet.curl --header "Content-Type: application/json" \ --request PUT \ --data '{"ship":"sampel-talled","json":"sampel-palnet"}' \ http://localhost:8080/~checkAuth
-
Send a DM from
~sampel-palnet
to~sampel-talled
at which contains the token returned in the first step (this is the authentication step, which in our text workflow is send a dm via dojo, however typically would be done via Urbit Visor).:dm-hook|dm ~sampel-talled ~[[%text 'RENV~jjr1W-ICCIlBr9ZVIxg']]
-
Check the authentication status of
~sampel-palnet
from~sampel-talled
and confirm that the user ship has been authorized.curl --header "Content-Type: application/json" \ --request PUT \ --data '{"ship":"sampel-talled","json":"sampel-palnet"}' \ http://localhost:8080/~checkAuth
-
Reheck the authentication status of
~sampel-palnet
from~sampel-talled
and confirm that the user ship is once again not authorized (/~checkAuth
is a one-time consume check, meaning that users must reauthorize themselves every time they want to login.)curl --header "Content-Type: application/json" \ --request PUT \ --data '{"ship":"sampel-talled","json":"sampel-palnet"}' \ http://localhost:8080/~checkAuth