ユーザー認証機能を実装しよう
📁 internet identity キャニスターを準備しよう
今回のプロジェクトでは、ユーザーの認証にInternet Identityを使用します。
Internet Identity とは?
Internet Identityは、ICPがサポートするユーザー認証のフレームワークです。ユーザーは、認証にラップトップの指紋センサーや顔認証システムなどのデバイスと**アンカー(Anchor)**と呼ばれる数字を紐付けることができます。その後、アンカーに紐づけたデバイスを利用して、さまざまなアプリケーションにサインアップし認証を行うことができます。詳しくはこちらのドキュメントを参照してください。
それでは、準備をしていきましょう!
Internet Identity用のキャニスター(Wasmモジュール)をGithubのリリースページか ら取得することができます。今回は、dfx.jsonファイル内にモジュールへのパスを直接指定し、Internet Identityキャニスターをデプロイしようと思います。
新たなキャニスターを追加するので、dfx.jsonファイルを編集しましょう。以下を参考に、internet_identity_divというキャニスター名と読み込むファイルのパスを指定しましょう。ここでは、"SilverDIP20"と"icp_basic_dex_frontend"の間に追記しています。
[dfx.json]
"SilverDIP20": {
"main": "src/DIP20/motoko/src/token.mo",
"type": "motoko"
},
"internet_identity_div": {
"type": "custom",
"wasm": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity_dev.wasm.gz",
"candid": "https://github.com/dfinity/internet-identity/releases/latest/download/internet_identity.did"
},
"icp_basic_dex_frontend": {
👤 認証ボタンを実装しよう
さて、ここからUIの作成を行なっていきましょう。まずは以下のようなヘッダーを作成します。ボタンを押したときに先ほど設定をしたInternet IdentityキャニスターにアクセスをしてユーザーのIDが取得できるようにします。

ここで実装する機能は、2つあります。
- ボタンが押されたときに、
Internet Identityキャニスターを呼び出す - 認証したユーザーのIDを取得する
まずは、機能を実装するファイルを作成します。
mkdir ./src/icp_basic_dex_frontend/src/components && touch ./src/icp_basic_dex_frontend/src/components/Header.jsx
icp_basic_dex_frontend/srcディレクトリ下に、componentsディレクトリとHeader.jsxファイルが作成されます。
src/
├── App.css
├── App.jsx
+├── components/
+│ └── Header.jsx
├── index.html
└── index.js
それでは、以下のコードをHeader.jsxファイルに記述しましょう。
[Header.jsx]
import { canisterId as IICanisterID } from "../../../declarations/internet_identity_div";
import { HttpAgent } from "@dfinity/agent";
import { AuthClient } from "@dfinity/auth-client";
export const Header = (props) => {
const { setUserPrincipal } = props;
const handleSuccess = async (authClient) => {
// 認証したユーザーの`identity`を取得
const identity = await authClient.getIdentity();
// 認証したユーザーの`principal`を取得
const principal = identity.getPrincipal();
setUserPrincipal(principal);
console.log(`User Principal: ${principal.toString()}`);
};
const handleLogin = async () => {
// アプリケーションが接続しているネットワークに応じて、
// ユーザー認証に使用するInternet IdentityのURLを決定する
let iiUrl;
if (process.env.DFX_NETWORK === "local") {
iiUrl = `http://localhost:8000/?canisterId=${IICanisterID}`;
} else if (process.env.DFX_NETWORK === "ic") {
iiUrl = "https://identity.ic0.app/#authorize";
} else {
iiUrl = `https://${IICanisterID}.dfinity.network`;
}
// ログイン認証を実行
const authClient = await AuthClient.create();
authClient.login({
identityProvider: iiUrl,
onSuccess: async () => {
handleSuccess(authClient);
},
onError: (error) => {
console.error(`Login Failed: , ${error}`);
},
});
};
return (
<ul>
<li>SIMPLE DEX</li>
<li className="btn-login">
<button onClick={handleLogin}>Login Internet Identity</button>
</li>
</ul>
);
};
ここからは、キャニスターとの接続部分に焦点を当てて説明をしていきます。それでは、コードを見ていきましょう。
ここで重要なのはhandleLogin関数です。最初に、デプロイを行ったネットワークに応じてアクセスするURLを指定します。
localであれば、デプロイをしたInternet Identityを指定ic