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

Cognitoの複数IDP認証でユーザを統合したい​

ryome
July 05, 2023

 Cognitoの複数IDP認証でユーザを統合したい​

Cognitoを使用して、CognitoユーザとGoogle IDP認証時のユーザを同一ユーザとして扱う方法を解説。

ryome

July 05, 2023
Tweet

More Decks by ryome

Other Decks in Technology

Transcript

  1. AdminLinkProviderForUserの説明 { "DestinationUser": { "ProviderAttributeName": "string", "ProviderAttributeValue": "string", "ProviderName": "string"

    }, "SourceUser": { "ProviderAttributeName": "string", "ProviderAttributeValue": "string", "ProviderName": "string" }, "UserPoolId": "string" } ・・・宛先ユーザ ・・・元となるユーザ ・・・CognitoユーザプールID リ ク エ ス ト ※ 元となるユーザが既に ユーザプールに存在する場合、 エラーとなる 宛先ユーザのidentitiesに元となるユーザ情報を追加する
  2. ここでCognitoのおさらい Cognitoとは? • Cognitoは、API ベースで実装されるモバイルアプリや Web アプリに ユーザ 認証機能を提供するサービス •

    ユーザプールとIDプールの2つの機能を提供(今回は「ユーザプール」を使 用) • ユーザプールのサインインは、FacebookやGoogleなどのソーシャルIDP、ま たはSAMLベースのIDPを経由して行うことができる 詳しくは以下を参照 https://pages.awscloud.com/rs/112-TZM- 766/images/20200630_AWS_BlackBelt_Amazon_Cognito_ver2.pdf
  3. >npx create-react-app web Creating a new React app in C:¥~¥web.

    ...省略 We suggest that you begin by typing: cd web npm start Happy hacking! >cd web >npm install aws-amplify npm WARN deprecated [email protected]: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. ...省略 To address all issues (including breaking changes), run: npm audit fix --force Run `npm audit` for details. React App作成 以下コマンドをPowerShellで実行する
  4. import React from 'react'; import ReactDOM from 'react-dom/client'; import {

    Amplify } from 'aws-amplify'; import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; import awsconfig from './aws-exports'; // Amplifyの設定 Amplify.configure(awsconfig); const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> ); // If you want to start measuring performance in your app, pass a function // to log results (for example: reportWebVitals(console.log)) // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals reportWebVitals(); src/index.jsを修正 以下のコードに修正する
  5. import React, { useEffect, useState } from 'react'; import {

    Auth } from 'aws-amplify'; function App() { const [isAuthenticated, setIsAuthenticated] = useState(false); useEffect(() => { // ログインチェック Auth.currentAuthenticatedUser() .then(user => setIsAuthenticated(true)) .catch(err => setIsAuthenticated(false)); }, []); return isAuthenticated ? <button onClick={() => Auth.signOut()}>ログアウト </button> : <button onClick={() => Auth.federatedSignIn()}>ログイン/サ インアップ</button>; } export default App; src/App.jsを修正 以下のコードに修正する
  6. const awsconfig = { Auth: { region: '【リージョン】', userPoolId: '【UserPoolId】',

    userPoolWebClientId: '【UserPoolWebClientId】', oauth: { domain: '【UserPoolDomain】', scope: ['openid'], redirectSignIn: '【CloudFrontURL】', redirectSignOut: '【CloudFrontURL】', responseType: 'code' } }, aws_appsync_graphqlEndpoint: '【GraphQLEndpoint】', aws_appsync_region: '【リージョン】', aws_appsync_authenticationType: "AMAZON_COGNITO_USER_POOLS", aws_appsync_apiKey: "null" }; export default awsconfig; src/aws-exports.js を作成 以下のコードに作成する 【リージョン】:Cognitoを作成したリージョン 【UserPoolId】:メモした【ユーザプールID 】 【UserPoolWebClientId】:メモした【クライ アントID】 【UserPoolDomain】:メモした【Cognitoドメ イン】 【CloudFrontURL】:http://localhost:3000
  7. >npm start …省略 You can now view web in the

    browser. Local: http://localhost:3000 On Your Network: http://192.168.XX.XX:3000 Note that the development build is not optimized. To create a production build, use npm run build. webpack compiled successfully React App起動 以下コマンドをPowerShellで実行する
  8. import AWS from 'aws-sdk'; AWS.config.update({ region: 'ap-northeast-1' }); const userPoolId

    = process.env.USER_POOL_ID; export const handler = async (event, context, callback) => { const cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider(); const params = { UserPoolId: userPoolId, Filter: `email="${event.request.userAttributes.email}"` }; const usersResult = await cognitoidentityserviceprovider.listUsers(params).promise(); if (usersResult) { const paramsLink = { DestinationUser: { ProviderAttributeValue: usersResult.Users[0].Username, ProviderName: 'Cognito' }, SourceUser: { ProviderAttributeName: 'Cognito_Subject', ProviderAttributeValue: event.userName.replace('Google_', ''), ProviderName: 'Google' }, UserPoolId: userPoolId, }; await cognitoidentityserviceprovider.adminLinkProviderForUser(paramsLink).promise(); } callback(null, event); }; Lambdaコード (index.mjs) 以下のコードに作成する
  9. { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "logs:CreateLogGroup",

    "Resource": "arn:aws:logs:【リージョン】:【アカウントID】:*" }, { "Effect": "Allow", "Action": "cognito-idp:ListUsers", "Resource": "arn:aws:cognito-idp:【リージョン】:【アカウントID】:*" }, { "Effect": "Allow", "Action": "cognito-idp:AdminLinkProviderForUser", "Resource": "arn:aws:cognito-idp:【リージョン】:【アカウントID】:*" }, { "Effect": "Allow", "Action": [ "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": [ "arn:aws:logs:【リージョン】:【アカウントID】:log- group:/aws/lambda/signup_cognito:*" ] } ] } Lambda ポリシー詳細 Lambdaのポリシーを以下に変更する 【リージョン】:Lambdaを作成したリージョン 【アカウントID】:AWSアカウントID