Slide 1

Slide 1 text

CognitoとAmplifyで爆速認証実装 レバレジーズ株式会社 オンライン診療事業 田中紘夢 2023/07/11

Slide 2

Slide 2 text

自己紹介

Slide 3

Slide 3 text

名前:田中紘夢(ひろむ) 出身:神奈川県横浜市 趣味:⚾🧖🏉🏖🍺 開発:TypeScript(React, Next.js, Nest.js)、趣味でFlutter 󰞵経歴 2021年3月 早稲田大学卒業 2021年4月 レバレジーズ新卒入社 2022年11月〜 オンライン診療事業に異動

Slide 4

Slide 4 text

今回のテーマ Cognito × Amplify Authを使った フロントエンド認証の実装例とTipsの紹介

Slide 5

Slide 5 text

IDaaS(特にCognito)を触ったことがない方や 導入を迷っている方にとって 少しでも参考になれば幸いです!

Slide 6

Slide 6 text

まずはじめに

Slide 7

Slide 7 text

オンラインで男性AGAの診察予約〜診療〜決済ができ、 家に薬が届きます。 今後男性AGA以外にも診療内容を拡大予定です。 をリリースしました!

Slide 8

Slide 8 text

オンラインで男性AGAの診察予約〜診療〜決済ができ、 家に薬が届きます。 今後男性AGA以外にも診療内容を拡大予定です。 をリリースしました!

Slide 9

Slide 9 text

AWS Amplifyとは AWSいわく「フロントエンドのウェブ/モバイルデベロッパーが AWS でフルスタックアプリケーショ ンを簡単に構築、出荷、ホストできる」サービス。 今回はAmplifyが提供しているSDKのなかのAuthライブラリを使って、cogintoの認証をフロント エンドで実装しました。

Slide 10

Slide 10 text

なぜcognitoなのか ・IDaaSを使って認証基盤の構築を実装面でも工数面でも楽にしたかった ・Auth0はコスト面、クオータの制限が見合わなかった ・Firebaseはコスト面、実装面で優位なもののセキュリティ面に課題あり →登録しているメールアドレスが簡単にわかってしまう(※) ※詳しく知りたい方はこちらの記事がおすすめです(https://zenn.dev/rdlabo/articles/c899eee25d0191) サービスの性質上センシティブな内容を扱う( AGA治療など)こともあり、登録されているメールア ドレスがわかってしまうリスクを回避する理由で Cognitoを採用

Slide 11

Slide 11 text

Amplify Authを使った認証実装例

Slide 12

Slide 12 text

Amplify Authで認証処理実装 ①Amplifyの初期化 Amplify.configure({ Auth: { region: "ap-northeast-1", userPoolId: "", userPollWebClientId: "", // federatedSignInを使う場合 oauth: { domain: "", scope: ["email", "openid", "aws.cognito.signin.user.admin"], redirectSignIn: "", redirectSignOut: "", responseType: "code" } } }) _app.tsxで以下を実行する

Slide 13

Slide 13 text

Amplify Authで認証処理実装 ②メールアドレスログインの実装 import { Auth } from "aws-amplify" const signInWithEmail = async (email, password) => { await Auth.signIn({ username: email, password: password, }) .then((response) => {}) .catch((error) => {}) } Auth.signInを実行するだけでOK

Slide 14

Slide 14 text

Amplify Authで認証処理実装 ③Googleログイン(アイデンティティプロバイダーを使った認証) Auth.federatedSignInを実行する。成功するとconfigureに書いたurlにリダイレクト import { CognitoHostedUIIdentityProvider } from "@aws-amplify/auth" import { Auth } from "aws-amplify" const signInWithGoogle = async () => { await Auth.federatedSignIn({ provider: CognitoHostedUIIdentityProvider.Google, }) }

Slide 15

Slide 15 text

Amplify Authで認証処理実装 ④セッション(jwt)の取得 AmplifyではlocalStorageもしくはcookieにjwtを自動で保持してくれるため currentSessionを呼び出すだけでセッション情報が取得可能 import { Auth } from "aws-amplify" const getAccessToken = async () => { const session = await Auth.currentSession() if (!session?.isValid()) { return null } return session.getAccessToken().getJwtToken() }

Slide 16

Slide 16 text

Amplify Authで認証処理実装 ⑤ログアウト Auth.signOutを呼び出すだけでOK アイデンティティプロバイダーのログインの場合はconfigureで指定したsignOutUrlにリダイレクト import { Auth } from "aws-amplify" const signOut = () => Auth.signOut()

Slide 17

Slide 17 text

Amplify Authとうまく付き合うTips

Slide 18

Slide 18 text

Amplify Authとうまく付き合うTips ①アイデンティティプロバイダー認証後の処理はHub.listenで const signInWithGoogle = async () => { await Auth.federatedSignIn({ provider: CognitoHostedUIIdentityProvider.Google, customState: "" }) .then((response) => { // ここに書いても動かない fetchUserFromOwnServer() }) } 例えばGoogleログインをするとリダイレクトするため thenやcatchで処理ができません

Slide 19

Slide 19 text

Amplify Authとうまく付き合うTips ①アイデンティティプロバイダー認証後の処理はHub.listenで Hub.listen("auth", async ({ payload: { event, data } })) => { switch (event) { case "signIn": { // ここでアイデンティティプロバイダーで認証完了したことが検知できる fetchUserFromOwnServer() } } } なのでHub.listenで認証状態の変化を監視してあげるといいです

Slide 20

Slide 20 text

Amplify Authとうまく付き合うTips ②アイデンティティプロバイダーの認証後のリダイレクト先を動的に変える Amplify.configure({ Auth: { // 省略 oauth: { // 省略 redirectSignIn: typeof window === "undefined" ? "固定値やenvから取得" : window.location.origin + window.location.pathname,, redirectSignOut: "", responseType: "code" } } }) cognitoには複数のリダイレクトURLを設定できますが、Amplifyの設定ではできません。 登録ページとログインページのurlが分かれている場合などは動的にセットしてあげるといいです。

Slide 21

Slide 21 text

Amplify Authとうまく付き合うTips ③アイデンティティプロバイダーの認証後に動的なパラメータを引き継ぐ cognitoではリダイレクトURLのワイルドカードの指定ができないため、動的なパラメータがつく場 合などはカスタムステートで渡してあげる必要があります const signInWithGoogle = async () => { await Auth.federatedSignIn({ provider: CognitoHostedUIIdentityProvider.Google, customState: JSON.stringify({ token: "何かしらの動的パラメータなど" }) }) }

Slide 22

Slide 22 text

Amplify Authとうまく付き合うTips ③アイデンティティプロバイダーの認証後に動的なパラメータを引き継ぐ Hub.listen("auth", async ({ payload: { event, data } })) => { switch (event) { case "customOAuthState": { const state = JSON.parse(data) // state.tokenと取れる } } } するとHub.listenでカスタムステートを取得することができます

Slide 23

Slide 23 text

Amplify Auth / Cognitoの辛いところ

Slide 24

Slide 24 text

Amplify Auth / Cognitoの辛いところ 先述の通り、Amplify AuthはjwtをデフォルトでlocalStorageもしくはcookie(http-onlyにはできな い)に保持するため、セキュリティ上の脆弱性となる可能性もあります。 http-onlyのcookieに保持するためにはサーバーの処理を噛ませる必要があり、 cognitoのデフォ ルトの機能では実装できません。 利便性とセキュリティ要件を踏まえて採用を検討する必要があります。 jwtをどこに管理するか

Slide 25

Slide 25 text

終わり