Cognitoマネージドログイン画面でsigninSilentが失敗する

今開発しているWebアプリでは、認証機構にAmazon Cogniotを利用している。いつのまにか導入されていたマネージドログイン画面は便利なので、早速用いることにした。

[アップデート] Amazon Cognito で「マネージドログイン」機能が導入され、ログインメニューのブランディングのカスタマイズが可能となりました | DevelopersIO

多分ホストUIをさらにカスタマイズできるようにしたものなのかな。個人開発なのであまりこだわっていないが、会社なら重要な機能だろう。

さて、開発中のWebアプリはSPAで、タブを開く度に認証を走らせる必要がある。このときCogniotのマネージドログイン画面を利用している際、サイレントサインインしようとしたらエラーが出た。リダイレクトしてサインインはできる。この状況について。

目次

エラーの状況:CSPで弾かれる

状況をもう少し詳細に書く。まず認証用のライブラリとして react-oidc-contextを利用している。これは

authts/react-oidc-context: Lightweight auth library based on oidc-client-ts for React single page applications (SPA). Support for hooks and higher-order components (HOC).

で、新しいタブで開くと改めて認証をとおさないといけないのだが、これは上記README.mdを見ると、Automatic sign-inでできる。

// index.jsx
const oidcConfig: AuthProviderProps = {
    ...
    userStore: new WebStorageStateStore({ store: window.localStorage }),
};
// src/App.jsx
import React from "react";
import { useAuth, hasAuthParams } from "react-oidc-context";

function App() {
    const auth = useAuth();
    const [hasTriedSignin, setHasTriedSignin] = React.useState(false);

    // automatically sign-in
    React.useEffect(() => {
        if (!hasAuthParams() &&
            !auth.isAuthenticated && !auth.activeNavigator && !auth.isLoading &&
            !hasTriedSignin
        ) {
            auth.signinRedirect();
            setHasTriedSignin(true);
        }
    }, [auth, hasTriedSignin]);

    if (auth.isLoading) {
        return <div>Signing you in/out...</div>;
    }

    if (!auth.isAuthenticated) {
        return <div>Unable to log in</div>;
    }

    return <button onClick={() => void auth.removeUser()}>Log out</button>;
}

export default App;

何をしているかと言うと、isAuthenticatedなど認証周りの値が得られなかった時は、auth.signinRedirect()を実行する。hasTriedSigninでループを防いでいる。

これは機能するんだが、リフレッシュトークンの有効期限自体が切れていると、マネージドログイン画面にぶっ飛ばされてしまう。Webアプリにアクセスするとログイン画面にぶっ飛ばされるのは中々強烈な体験なので、これは避けたい。

なので、バックグラウンドでiframeを使ってサインインを実行するらしいauth.silentSignin()を使いたい。しかしこれを使うと、マネージドログイン画面側のCSPにより弾かれエラーが出てしまうようだった。

対応:カスタムドメインの設定

それでしばらく困っていて、「リフレッシュトークンの有効期限を10年にして10年後に考えよう」などと追い詰められていたのだが、よくよく考えたらCSPということはドメインの問題なのではないかと思われた。

で、Cognitoのカスタムドメイン機能を使って、サブドメインとしてauthを設定し、COGNITO_DOMAINの設定をカスタムドメインに置き換えたところ、無事 auth.silentSignin() がとおるようになった。

言われてみれば「そうか」という感じなのだが、実際には丸一日くらい対応悩んでいた。AIに聞いても堂々巡りだったし。なんかコードに引きずられてしまうのか、コードの話ばかりで「いやそれじゃできないんだって」という押し問答をする不毛な時間を過ごした。

まぁとりあえずできてよかったが、それはそれとして、今開発しているのは別に大した情報をもったサービスではなく、再ログインを促すのもなんだし、リフレッシュトークン10年にしてもいいな、とは思った。

久しぶりの技術記事

久しぶりに技術系の記事を書いた。何もしていなかったということはないのだが(むしろ頑張っていたと思う……)最近技術系の備忘録は全部AIに書かせて別館行きにしていたために。なんだか既に別館のほうがアクセスが多く、やる気を失っている今日この頃である。

AIによる技術記事 備忘録 | AIに同じことを聞かない

最近は技術記事以外もAI化しつつある。文字列になった人間の感性を食べて生きている僕には、世知辛い世の中になった。

本サイトはUXを悪くするevilなGoogle広告を消しました。応援してくださる方は おすすめガジェット を見ていってください!
よかったらシェアしてね!
  • URLをコピーしました!

コメント

コメントする

目次