Closed6
React.js + AWS Cognito でMetaMask login を実装する
の続き。Client 側を実装する。
と言ってもこちらはJSなのでどこかの例をそのまま使えば簡単に終わるはず(楽観)
Client side の実装はSDK にしろamplify にしろsignIn として抽象化されたものを利用するようで、custom authentication flow をinitiateAuth から始めるコードが全然見つからない。
自分で実装しないといけなさそうだ。。
ということでamazon-cognito-identity-js を読んでみる。
Use case 25. Authenticating a user with a passwordless custom flow.
が該当していそう。
Cognito への処理はこんな感じになった。
type Props = {
username: string;
callback: IAuthenticationCallback;
};
export const Authenticate = ({
username: username,
callback: callback,
}: Props) => {
const user = new CognitoUser({ Username: username, Pool: userPool });
user.setAuthenticationFlowType("CUSTOM_AUTH");
const details = new AuthenticationDetails({
Username: username,
});
user.initiateAuth(details, callback);
};
onSuccess, onFailure にAuthContext へのdispatch、customChallenge にweb3.eth.personal.sign() を実行する関数をそれぞれ渡す。
あとはこの記事のコードをベースにAuthProvider とlogin component を調整すれば完了。
ハマりポイント。
const accounts = await window.ethereum.request({
method: 'eth_requestAccounts',
});
const address = accounts[0];
はwallet address をlowercase のhex文字列(通常のethereum wallet address)で取得する。
これに対し、crypto 関連のライブラリではchecksum 可能なcase-sensitive なaddress を利用することが多く*、そのため単純な文字列の比較が失敗してしまう。(例えばLambda の実装に利用したgo-ethereumなど。)
上記の代わりに
const accounts = await web3.eth.getAccounts();
const address = accounts[0];
をで取得したところcase-sensitive な文字列が取得できたためこちらを利用した。
この辺りの仕様の背景はこちらを参照。
このスクラップは2022/03/17にクローズされました