Share
Embed
Cognitoの複数IDP認証でユーザを統合したい
Cognitoを使用して、CognitoユーザとGoogle IDP認証時のユーザを同一ユーザとして扱う方法を解説。
ryome
July 05, 2023
Transcript
33 slides
-
AdminLinkProviderForUserの説明 { "DestinationUser": { "ProviderAttributeName": "string", "ProviderAttributeValue": "string", "ProviderName": "string"
}, "SourceUser": { "ProviderAttributeName": "string", "ProviderAttributeValue": "string", "ProviderName": "string" }, "UserPoolId": "string" } ・・・宛先ユーザ ・・・元となるユーザ ・・・CognitoユーザプールID リ ク エ ス ト ※ 元となるユーザが既に ユーザプールに存在する場合、 エラーとなる 宛先ユーザのidentitiesに元となるユーザ情報を追加する -
ここで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 -
手順 1. Google OAuthクライアント作成 2. Cognito ユーザプール作成 3. Cognito ユーザプールにGoogle
IDP追加 4. Lambdaトリガーを追加 -
>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で実行する -
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を修正 以下のコードに修正する -
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を修正 以下のコードに修正する -
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 -
>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で実行する -
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) 以下のコードに作成する -
{ "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 -
参考文献 • https://docs.aws.amazon.com/ja_jp/cognito-user-identity- pools/latest/APIReference/API_AdminLinkProviderForUser.html • https://tseki.hatenablog.com/entry/2021/06/20/013646 • https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Cog nitoIdentityServiceProvider.html#adminLinkProviderForUser- property
• https://docs.aws.amazon.com/cognito-user-identity- pools/latest/APIReference/API_AdminLinkProviderForUser.html