Integrating Internet Identity
This guide demonstrates an example of how to integrate Internet Identity as an application authentication service. In this example, a user can interact with the application's website to log in with their identity and then call a backend canister's function whose behavior depends on the identity of the caller.
For simplicity, we use the whoami
function that simply returns the caller's principal. (While real-world use cases for Internet Identity are out of scope of this guide, note that the most common use case is authentication, for example, letting the backend process certain requests only from an authorized caller while rejecting calls from everyone else.)
- Prerequisites
You can open this project in ICP Ninja, a web-based IDE for temporary project deployments, or clone the "Who am I?" sample from GitHub. Keep reading if you want to develop locally from scratch or extend an existing project with an Internet Identity integration.
Step 1: Get an ICP dapp project.
You may either create a new project or open an existing project.
To crete a new project:
- Motoko
- Rust
dfx new internet_identity_app --type=motoko --frontend react --extras internet-identity
cd internet_identity_app
dfx new internet_identity_app --type=rust --frontend react --extras internet-identity
cd internet_identity_app
The --extras
flag will add the pullable version of the Internet Identity canister to your project. A pullable canister is a canister that provides a public service at a static canister ID. Learn more about pullable canisters.
For a new project, add the follwoing canister configuration to the project's dfx.json
file:
- Motoko
- Rust
loading...
loading...
If you already have a project that was not created with the extra Internet Identity feature, you can modify the project to use the pullable Internet Identity canister.
In this tutorial, we use frontend code that assumes that the Internet Identity canister is installed with ID rdmx6-jaaaa-aaaaa-aaadq-cai,
the same ID as this canister has on the mainnet.
To ensure the correct Internet Identity canister ID, be sure to add "specified_id": "rdmx6-jaaaa-aaaaa-aaadq-cai"
to your .canisters.internet_identity
section in dfx.json.
Step 2: Edit backend code.
To add a simple "Who am I?" function, insert the following code into the backend canister's source code file:
- Motoko
- Rust
loading...
Compiling this Motoko code requires the Mops package manager.
So make sure the project has a mops.toml file in its root.
If not, install Mops and simply run the following command to initialize mops.toml:
mops init -y
loading...
Don't forget to add the whoami
function to the Candid definition, which is used for generating frontend bindings:
loading...
Step 3: Edit frontend code.
In the frontend canister code, add a method to the App
class to call the backend function and initialize the auth client:
loading...
Make sure to always create a single AuthClient
instance on page load and reuse it within your click handlers.
Install the required npm
package:
cd src/internet_identity_app_frontend
npm install @dfinity/auth-client@^3.0.0
cd ../..
Make sure that all @dfinity/<package> dependencies in package.json are the same version.
Step 4
Make sure you have a local development environment:
dfx start --clean --background
If you see the error Error: dfx is already running
, that's fine, it just means that your local development environment is ready.
Sometimes you might see a local network port being occupied by another process, preventing dfx
from being able to bind
the local network to that local port. To diagnose which process is occupying a particular port number, e.g., 1234
,
run lsof -i :1234
(the actual port number will be reported in the error from the dfx start
command).
Step 5: Deploy the application:
dfx deploy
If you see an error, e.g., Canister rdmx6-jaaaa-aaaaa-aaadq-cai is already installed.
this means your local development environment needs to be restarted:
dfx stop
Once the above command finishes, go back to Step 4.
Open the frontend URL that is returned in the deployment output. Your dapp's frontend will be displayed.
If you are developing using the Safari web browser, you need to change the value returned for the local development environment to http://localhost:4943?canisterId=<canister_id>
.
Click the "Login" button. You'll be redirected to the Internet Identity frontend. Since you're running this locally, you will be using a local, non-production Internet Identity. To create one, follow the on-screen steps.
Click the "Who am I" button and it should return your Internet Identity principal:
Your principal is: 5uylz-j7fcd-isj73-gp57f-xwwyy-po2ib-7iboa-fdkdv-nrsam-3bd3r-qqe
The above principal is an example. The principal returned will be different based on the account and the environment where the application and Internet Identity are running.
Local frontend development
When modifying this example's frontend, it is recommended to develop using a local development server instead of using the deployed frontend canister. This is because using a local development server will enable Hot Module Reloading, allowing you to see any modifications made to your frontend instantaneously, rather than having to redeploy the frontend canister to see the changes.
To start a local development server, run npm run start
. The output will contain the local address the project is running at, such as 127.0.0.1:4943
.