【IC】ローカルでインターネットアイデンティティと連携する方法

インターネットアイデンティティをつかってインターネットコンピューターの認証の仕組みの大枠をつかみたい人向けの記事です。

インターネットコンピューターのサンプルはreactやtypescriptでしっかりで作りこまれているため、両技術に明るくない人にとっては、インターネットアイデンティティとの連携部分だけみようとすると、切り分けが少し難しくなります。

そこで、javascriptだけで認証するサンプルをつくりましたので、そちらを紹介します。ログインからログアウトまで一連の流れがわかる内容になっています。興味のある方はどうぞ。

ローカルでインターネットアイデンティティと連携する方法

インターネットアイデンティティとの連携イメージ

今回のサンプルの一連の流れです。

サンプルで確認できること

サンプルでは次の流れが確認できます。

  • インターネットアイデンティティでログイン
  • ログイン後ブラウザ上で認証の確認
  • バックエンドキャニスターでの認証の確認
  • ログアウト

サンプルのリポジトリ

https://github.com/nry0629/ii_client_sample

メインの2つのファイル

    /src/ii_client_sample_assets/src/index.js
    /src/ii_client_sample/src/lib.rs

インターネットアイデンティティの連携と認証情報の確認はこの2つのファイルが中心になります。コード量は100行無いので全体感はそちらでつかんでいただけると思います。

実際に動かしながら確認してみる

準備

ローカルでのインターネットアイデンティティの展開

あらかじめ、インターネットアイデンティティをローカルに展開しておきます。Ubuntuをお使いの方は次の手順で動かせます。

>> Ubuntuでインターネットアイデンティティを動かす方法

サンプルの展開

次に、README.mdに手順があるので、サンプルをローカル環境で展開します。

インターネットアイデンティティでログイン

それでは実際にインターネットアイデンティティと連携している部分のコードを見ていきます。

AuthClientがメイン

インターネットアイデンティティと連携するには、まず「AuthClient」というクラスを使用します。


ログイン部分のコードはこちら


では詳しく見ていきます。

loginメソッド
  1. identityProviderでインターネットアイデンティティのURL指定
  2. onSuccessでログイン完了後の処理
  3. onErrorで失敗した時の処理
identityProviderでインターネットアイデンティティのURL指定

生成メソッドでauthClientを作成したら、loginメソッドで即インターネットアイデンティティと連携が開始されます。

identityProviderはローカル開発で使用する値になっていますね。なお、実際のインターネットコンピューターのメインネットで動かすときには、「https://identity.ic0.app/#authorize」が指定されます。

問題なく動けば、指定したURLを別タブや別ブラウザで開くことができます。

ログイン後ブラウザ上で認証の確認

続いて通信完了後の処理です。onSuccessの中身を見てみましょう。


ログインが完了するとauthClientにある2つのメソッドを通して認証状態と自分のプリンシパルIDを取得できます。

認証状態の取得

プリンシパルIDの取得

バックエンドキャニスターでの認証確認

では続いて自分のキャニスターでも認証されているか確認します。「callボタン」を押下すると、バックエンドとして配置した自分のキャニスターへ通信をおこないます。

サンプルではキャニスターとの通信を

  • クライアントの用意
  • 通信実行

に分けています。

クライアント(Actor)の用意

今回のサンプルではgetActorというメソッドでバックエンドと通信するためのクライアントを用意します。


getAcotorメソッドで認証している場合と匿名の場合とで分けています。そちらのメソッドで紹介します。

キャニスターと通信するためのjsコンポーネントはcandid(src/ii_client_sample/ii_client_sample.did)を解析して自動で作られますので、それらを使用していきます。


ii_client_sampleはActorとよばれ、自分のキャニスタークライアントに相当します。すぐさま匿名アクセスで使用できるActorクラスがcandidをもとに自動生成されたコードに含まれているので、認証情報を使用しない場合はそれを使うだけでOKです。

匿名アクセスするためのActorは、サンプルでは判別できるように、AnonymousIiClientSampleと名前を付けてインポートして使っています。


しかし、インターネットアイデンティティで認証した場合は、自分でActorを組み立てる必要があります。createActorメソッドが用意されているのでそちらを使用します。サンプルでは、createIiClientSampleBaseActorという名前でインポートしてます。


第一引数にキャニスターIDを、そして第二引数のプロパティに認証済みのIDを渡します。

キャニスターと通信

実際にキャニスター側のスマートコントラクトを呼び出すのはActorのメソッドを使うだけ。


呼び出し完了の後は戻ってきた値を画面に表示してます。

キャニスター側の動作

ちなみにキャニスター側では、呼び出した人が誰か?という情報だけ返却してます。

rustでの認証確認

キャニスターでは、callerメソッドで呼び出し元を確認できます。

認証済みであれば、プリンシパルIDが含まれていて未認証であれば”2vxsx-fae“になります。認証可否を判定する一つの方法として、“2vxsx-fae”をサンプルでは利用しています。

javascript側にはis_authenticatedメソッドがありましたが、キャニスターではis_authenticatedに相当するメソッドが現時点で用意されてないので、自分で判定する必要があります。

motokoでの認証確認

なお、キャニスター側であってもmotokoを使っている場合はisAnonymousメソッドという類似メソッドが用意されているので、そちらを転用し判定できます。

ログアウト

ブラウザ側でのログアウトはどのようにやるのか。こちらはlogoutメソッドを呼び出すだけでOKです。


サンプルではわかりやすくするため、画面の情報を消していますが、認証情報の本体はブラウザのローカルストレージに格納されており、

ログアウトすると

ストレージの情報が消えているのが確認できます。

インターネットコンピューターは既存Webよりも認証が簡単

OAuthと比較すると、バックエンドとIDプロバイダーを繋ぐためのコードを書いてません。インターネットコンピューターではIDプロバイダー(インターネットアイデンティティ)と連携だけのコードしかないので、認証を既存WEBより簡単にできました。書かないといけないコード量が少ないのがうれしいですね。

補足:インストールしたパッケージ

本サンプルはdfxで作られるhelloプログラムをもとに作っています。インターネットアイデンティティと連携するために、いくつかのパッケージを追加しています。参考までに。

npm

  • “@dfinity/auth-client”: “^0.11.0”,
  • “@dfinity/authentication”: “^0.11.0”,
  • “@dfinity/identity”: “^0.11.0”

cargo

  • ic-types = “0.3”
  • serde = “1.0.136” 
  • serde_bytes = “0.11.5”

まとめ

最後振り返ります。

  • 認証した状態でキャニスターと通信するには自分でActorを作る必要がある
  • 認証情報はローカルストレージに保存される
  • 既存Webよりも簡単に認証できる

私はいくつかのIDプロバイダーと連携するコードを書いてきましたがバックエンドとIDプロバイダーとのやり取りを書かないのは衝撃でした。というかそれありきでドキュメントを読んでいたので、だいぶ遠回りしました。

冒頭でも述べましたが、インターネットコンピューターにあるサンプルは作りこまれているので、本記事のサンプルがその入口になればうれしいです。

では。