Alternative frontend origins
If your application has reached the stage where you want to change domain names, and you have been authenticating with Internet Identity (II), you will want to make sure that your users can seamlessly keep the same principals they have already been using. To support this functionality, you can configure your application for alternative frontend origins using this guide.
You may need this guide if you are doing any of the following:
- Moving from
<canister-id>.icp0.io
to a custom domain. - Asking users to log in at
/login
instead of/
. - Supporting users using
raw.icp0.io
. - Configuring multiple apps in your organization to use the same principals.
Constraints
Currently, a maximum of 10 alternative origins can be listed.
Internet Identity will only follow this specification when the origin configuring these alternatives is hosted on a canister using certified assets.
For more information, see the Internet Identity specification.
Configuring alternative origins
For this example, you will have two domains, A and B. A will be the derivation origin, and B will be the alternative domain. To help illustrate this model, consider this website, which is hosted both at https://xxxxx.icp0.io
and https://www.yourcustomdomain.com
.
In this example, A would be https://xxxxx.icp0.io
.
B would be the alternative origin, or https://www.yourcustomdomain.com
.
Setting the derivation origin
If you are using Internet Identity, you are probably using AuthClient. Therefore, on the code for the B origin, you need to set the derivationOrigin
to the AuthClient to A.
const authClient = await AuthClient.login({
//...
derivationOrigin: "https://xxxxx.icp0.io",
});
Note that for the AuthClient
on A the field derivationOrigin
can be omitted.
For more details about the login options in the AuthClient, see its documentation.
Listing alternative origins
On origin A, you need to provide an endpoint .well-known/ii-alternative-origins
that tells Internet Identity that B is a valid alternative origin.
The response of this endpoint must be a valid JSON object with an alternativeOrigins
key, containing an array of strings:
{
"alternativeOrigins": ["https://www.yourcustomdomain.com"]
}
Requirements:
- Maximum of 10 alternative origins can be listed.
- No trailing slash or paths should appear in the URL.
- Order doesn't matter.
Note that there is no need to have .well-known/ii-alternative-origins
on origin B.
Asset canister
Most developers implement their frontend applications using the Asset Canister. Therefore, we provide a tutorial on how to set up the alternative origins endpoint with it.
Adding the ii-alternative-origins
config file
If your frontend canister is currently configured to deploy assets from a dist
folder, make sure to update the sources
for your canister to include both:
"source": [
"dist",
"src/assets"
]
Inside of src/assets
, create a .well-known
folder, and add a file named ii-alternative-origins.
The file needs to be exactly named ii-alternative-origins
, with no file extension. The content inside will be formatted as JSON, but the file should not end with .json
.
Inside of the file, list your alternative origins for A, which is B in our example. It will look something like this:
{
"alternativeOrigins": ["https://www.yourcustomdomain.com"]
}
Now, your project should look something like this:
├── dfx.json
├── src
│ ├── assets
│ │ ├── .well-known
│ │ │ └── ii-alternative-origins
Configuring your frontend canister
Because the dot syntax in .well-known
ordinarily will be treated as "hidden" by the file system, the frontend canister will need to be configured to upload your document. To configure the frontend canister, create a new file, .ic-assets.json
. .ic-assets.json
needs to be placed inside a directory listed in sources
for your canister, so you can use src/assets
again. Your new list of files should look like this:
├── dfx.json
├── package.json
├── src
│ ├── project_frontend
│ │ ├── src
│ │ │ ├── .ic-assets.json
│ │ │ ├── .well-known
│ │ │ │ └── ii-alternative-origins
Then, configure the .well-known
directory to be included with:
[
{
"match": ".well-known",
"ignore": false
},
{
"match": ".well-known/ii-alternative-origins",
"headers": {
"Access-Control-Allow-Origin": "*",
"Content-Type": "application/json"
},
"ignore": false
}
]
This includes a general rule to not ignore the .well-known
directory and rules to deliver the ii-alternative-origins
with access control and content-type headers.
Now, all you need to do is deploy your canisters (both A and B).
From now on, when you attempt to authenticate from origin B, you will get back the same principal you get while using A.
For more information, see the Internet Identity specification for Alternative Origins.