Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CognitoとAmplifyで爆速認証実装

 CognitoとAmplifyで爆速認証実装

More Decks by レバレジーズTechアカウント

Transcript

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

    View Slide

  2. 自己紹介

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  6. まずはじめに

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  11. Amplify Authを使った認証実装例

    View Slide

  12. 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で以下を実行する

    View Slide

  13. 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

    View Slide

  14. 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,
    })
    }

    View Slide

  15. 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()
    }

    View Slide

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

    View Slide

  17. Amplify Authとうまく付き合うTips

    View Slide

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

    View Slide

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

    View Slide

  20. 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が分かれている場合などは動的にセットしてあげるといいです。

    View Slide

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

    View Slide

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

    View Slide

  23. Amplify Auth / Cognitoの辛いところ

    View Slide

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

    View Slide

  25. 終わり

    View Slide