はじめに
ログイン時はログイン画面を開いたらトップにリダイレクト、ログインしていないのにトップ画面を開いたらログインにリダイレクトといった対応を入れることはよくあると思います。
私も同じように対応するにあたり、ログインチェックしてリダイレクトをするような記事は多々あるのですが自分たちの環境にあったものを探すのに苦労しました。
今回は表題のような構成のSSG環境におけるログインチェック・リダイレクトをしたい時に採用した方法についてまとめました。
また、ログイン管理の仕組みはaws-amplify
のAmplify Auth
を例としております。
最初に結論
Pluginとして共通メソッドのようなものを実装し、各画面読み込み時に呼び出すようにしました。
declare module '@nuxt/types' {
interface Context {
$redirectLoginByAuthState(): Promise<void>
}
}
const myPlugin: Plugin = (context) => {
context.$redirectLoginByAuthState = () => {
const { Auth } = withSSRContext({ req: context.req })
return new Promise(async (resolve, reject) => {
try {
await Auth.currentAuthenticatedUser()
resolve()
} catch (error) {
context.redirect('/login')
// rejectするとfetchやasyncDataで呼び出している時に死んでしまうので失敗時もresolve
resolve()
}
})
}
}
export default myPlugin
実装パターン
Middleware
export default function (context) {
if (!isLogin) { // ※トークン有無等でログインチェック
context.redirect('/login')
}
}
今回の構成では、S3にデプロイして確認するとF5更新(SSRリロード)した時に呼び出されなかったため無しとしました。
Plugins + NavigationGuard
Pluginを作成して、VueのNavigationGuardで処理する方法です。
import { Plugin } from '@nuxt/types'
import { withSSRContext } from 'aws-amplify'
const RouterAuthPlugin: Plugin = (context, inject) => {
const { Auth } = withSSRContext({ req: context.req })
context.app.router?.beforeEach(async (to, from, next) => {
// isRequiresAuthはnuxt.config.jsでRouteごとに付与しておく想定
if (to.matched.some((record) => record.meta.isRequiresAuth)) {
try {
await Auth.currentAuthenticatedUser()
return next()
} catch (error) {
return next({
path: '/login',
})
}
}
next()
})
}
export default RouterAuthPlugin
NavigationGuardという専用のものがあるので使いたかったですが、route.metaに付与するのが悪いのか、nuxt generate
すると生成時にHTMLの中身が別の画面とすり替わる現象が発生してしまいました。
Pluginsでメソッドを作成して各画面で呼び出し
結論となった方法です。
一番愚直な実装になってしまいましたが、今回は消去法でこの方法を採用しました。
おわりに
上手くいかず消去法で選択する形になってしまいましたが、結論の形も悪いことばかりではなくシンプルで分かりやすいかなとも思っております。
こんな方法もあるよとか、ここが悪いせいで上手くいかなかったのでは等あればコメントいただけると幸いです。
宣伝
株式会社start-up studioでは、コーポーレートガバナンス領域のDX推進を目指しております。
その第一弾として、複雑・膨大・専門的という三重苦を抱える決算開示業務のプロセスを劇的に効率化する「Uniforce -決算開示業務ナビゲーション- 」をリリースしました。
ご興味のある方はお問い合わせください!
https://startup-studio.co.jp/news/e4spzygrs/