今開発しているWebアプリでは、認証機構にAmazon Cogniotを利用している。いつのまにか導入されていたマネージドログイン画面は便利なので、早速用いることにした。
[アップデート] Amazon Cognito で「マネージドログイン」機能が導入され、ログインメニューのブランディングのカスタマイズが可能となりました | DevelopersIO
多分ホストUIをさらにカスタマイズできるようにしたものなのかな。個人開発なのであまりこだわっていないが、会社なら重要な機能だろう。
さて、開発中のWebアプリはSPAで、タブを開く度に認証を走らせる必要がある。このときCogniotのマネージドログイン画面を利用している際、サイレントサインインしようとしたらエラーが出た。リダイレクトしてサインインはできる。この状況について。
エラーの状況:CSPで弾かれる
状況をもう少し詳細に書く。まず認証用のライブラリとして react-oidc-context
を利用している。これは
で、新しいタブで開くと改めて認証をとおさないといけないのだが、これは上記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化しつつある。文字列になった人間の感性を食べて生きている僕には、世知辛い世の中になった。
コメント