Closed1
【Next Cognito Amplify】ログイン管理方法
何について書く?
- ログイン状態の管理方法
内容
まずNG例(冗長化してかつ、Amplifyのログイン情報を取得しない方法)
ポイント:各ページで ログインステートを更新し、その情報により、ヘッダー・フッターの表示制御を行っていた。ログアウトされるとログインステートがfalseになり、ヘッダーなどは非表示にされるとともに各ページに設置されたwithAuthenticatorによりログイン画面に戻る仕組み。
- ①グローバルステート準備(recoil)
import { atom } from 'recoil'
const loginState = atom({
key: 'login',
default: false
})
export default loginState
- ②グローバルステートの影響範囲を設定(_app.tsx)
Amplify.configure(awsconfig)
const Test = ({ Component, pageProps }: AppProps): JSX.Element => {
const islogin = useRecoilValue(loginState)
return (
<>
<RecoilRoot>
<Head>
<title>Test</title>
</Head>
{islogin ?
<>
<Header />
<Component {...pageProps} />
<Footer />
</>
:
<Component {...pageProps} />
}
</RecoilRoot>
</>
)
}
export default Test
- ③各ページの記載(index.tsxはじめ、すべてにwithAuthenticatorをつけていた。)
const TestIndex = () => {
const setLogin = useSetRecoilState(loginState)
useEffect(() => {
setLogin(true)
}
,[])
return (
<>
<h1>Test</h1>
</>
)
}
export default withAuthenticator(TestIndex)
改善後のベストプラクティス(Amplifyのログイン情報を取得する方法)
上記NGパターンの①②はそのまま残しプラス2つ(ユーザー情報用のグローバルステートとログイン処理用コンポーネントを準備)及び各ページの記載変更を行う。
- ④ ユーザー情報格納用のグローバルステート
import { atom } from 'recoil'
const userState = atom({
key: 'user',
default: {
userName: ''
},
})
export default userState
- ⑤ログイン共通処理(ここでグーグルアナリティクスなどの記載も可能)
export const testAuth = () => {
const [isLoaded, setIsLoaded] = useState(false) //ステート:読み込み
const [isLogined, setIsLogined] = useRecoilState(loginState) //グローバルステート:ログイン状態
const [userInfo, setUserInfo] = useRecoilState(userState) //グローバルステート:ユーザー情報
useEffect(() => {
const fetchUserInfo = async () => {
const userInfo = await Auth.currentUserInfo()
if (!userInfo) {
setUserInfo(undefined) //ユーザー無し
setIsLoaded(true) //読み込みは出来た
setIsLogined(false) //ログインしていない
return
}
setUserInfo({
userName: userInfo.username, //ユーザー情報も格納
})
setIsLoaded(true)// 読み込みできた
setIsLogined(true)// ログインしている
}
fetchUserInfo()
}, [isLogined]) //ログイン状態が変更されるたび呼ばれる。
return { isLoaded, userInfo } // 読み込み結果と、ユーザー情報を返す。
}
- ⑥トップページ からsetLoginの記述削除
const TestIndex = () => {
useEffect(() => {
}
,[])
return (
<>
<h1>Test</h1>
</>
)
}
export default withAuthenticator(TestIndex)
- ⑦他のページからはwithAuthenticatorをすべて削除 代わりにtestAuthを使用する。
const anotherPage = () => {
const router = useRouter()
const { isLoaded, userInfo } = testAuth()
useEffect(() => {
if (!isLoaded) return
if (!userInfo) {
router.push('/')
return
}
}, [isLoaded, userInfo])
return (
<div>
別ページです。
</div>
)
}
export default anotherPage
このスクラップは2022/04/17にクローズされました