AWS Cognitoを設定したのですが、時間がたつと忘れてしまいそうだったので、備忘録として残しておきます。
皆さんのお役に立てられればうれしいです。
今回、備忘録に残すのは、タイトルにある通り、AWS Cognitoで管理するユーザIDとして、外部のソーシャルIDであるGoogleアカウントや、Yahoo・LINEアカウントを利用できるように設定する手順です。
なかなか初めて触るWebサイトで、ユーザID・パスワードを新規に入力してアカウントを作ってもらうのはユーザにとって負担ですし、ユーザもたくさんのサイトのユーザID・パスワードを覚えておくのはたいへんです。
さて、YahooとLINEアカウントを利用できるようにする、としていますが、正しくは、OpenID Connect(略してOIDC)のアカウントを利用できるようにする、といったほうが正しいかもしれません。AWS Cognitoの機能を使えば、YahooやLINEに限らず、OpenID Connectに準拠していれば、そのアカウントをAWS Cognitoに紐づけることが(基本的には)可能のようです。
まずは、情報入手元の一覧です。
-
AWSマネージメントコンソール
-
ここから、AWS Cognitoの設定をしていきます。
-
AWS Cognito
- https://aws.amazon.com/jp/documentation/cognito/?id=docs_gateway
- ここから、Cognitoの開発ガイドのPDFがダウンロードできます。日本語です。
-
Google Cloud Platform Console
- https://console.cloud.google.com
- Googleアカウントを扱えるようにGoogle側に設定が必要です。
-
LINE Developer Console
- https://developers.line.me/ja/
- LINEアカウントを扱えるようにLINE側に設定が必要です。
-
Yahoo!デベロッパーネットワーク
- https://developer.yahoo.co.jp/
- Yahooアカウントを扱えるようにYahoo側に設定が必要です。
[2018/12/17 追記]
たまたま、Yahoo!デベロッパーネットワークのページを見てもう一度Cognito連携を試してみたら、
連携できたので、追記しました。
[2019/7/11 訂正]
アプリクライアントのgrantが間違っていました。ご指摘いただきありがとうございました!
AWS Cognitoユーザープールの作成
とにもかくにも、まずは各種ユーザIDを引き受けるAWS Cognitoのユーザープールを作成します。
GoogleアカウントやLINEアカウントを紐づける前に、まずはAWS Cognito単体で、ユーザIDのサインアップ(ユーザ登録)・サインイン(ログイン)ができるようにします。
AWSマネージメントコンソール ⇒ AWS Cognitoを選択します。
以下ショートカットも張っておきます。リージョンは東京を選択しました。
https://ap-northeast-1.console.aws.amazon.com/cognito/home?region=ap-northeast-1
ここから、「ユーザープールの管理」⇒「ユーザープールを作成する」を選択して、ユーザープールを作成します。
適当なプール名(たとえば、「test-pool」)を付けます。
ここでいくつか注意点があります。
途中で、「どの標準属性が必要ですか?」というところで、ユーザ登録時に必須の属性を指定します。本人確認やパスワード忘れ対策のために、通常は「email」を選択することが多いかと思います。
「email」を選択した場合には、これから連携する外部のソーシャルIDからユーザIDを連携させる際にも、Emailアドレスを取得できることが前提条件となります。ソーシャルIDだけしか扱わないのであれば、emailは必須ではありませんが、AWS Cognitoユーザープールの機能を使って自身でもユーザID・パスワードを発行するのであれば、emailがないのは非常に使いにくくなります。
「エンドユーザーをどのようにサインインさせますか?」や、「どの標準属性が必要ですか?」のところは、後で変更できないので、理解が進んだら、もう一度作りなおす覚悟でいきます。
あとは適当に。
AWS Cognitoアプリクライアントの作成
次に、作成したユーザープールを利用するアプリケーションを登録します。
今回は、Webアプリケーションを対象としたく、WebアプリのURLに対してアプリクライアントIDを払い出します。
AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「アプリクライアント」を選択します。
アプリクライアントの登録画面が表示されます。
適当なアプリクライアントIDの名前を付けます。例えば、「test-client-appli」とします。
クライアントが信頼できないWebアプリであれば、「クライアントシークレットを生成」のチェックボックスをOffにします。
これで、26文字ほどの乱数っぽいアプリクライアントIDが生成されました。
次に、AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「アプリクライアントの設定」を選択します。
さきほどは、とりあえずアプリクライアントIDを生成しましたが、これを実際のWebアプリに紐づけます。
紐づけは、WebアプリのURLに対して行います。
とりあえず、 https://localhost:3001/ とでもしておきます。後で正式なURLに変えます。
コールバックURLとサインアウトURLに、そのURLを記入しておきます。
以下のチェックボックスをOnにします。
- 有効なIDプロバイダ:Cognito User Pool
- 許可されているOAuthフロー:Authorization code grant
- 許可されているOAuthスコープ:email、openid
AWS Cognitoドメイン名の決定
AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「ドメイン名」を選択し、ドメイン名を決定します。
ソーシャルID連携のために、外部のソーシャルIDのサーバとの連携はAWSのCognitoがよろしくやってくれるので助かるのですが、このドメイン名が外部ソーシャルIDのサーバから見て話す相手が自身の管理するCognitoであることを識別するためのものです。また、ユーザがサインアップ・サインインのWebページを自身で作ることなく、あらかじめ用意してくれており、それを呼び出すためのURLでもあります。
ドメイン名で識別するので、「ドメインのプレフィックス」のところに適当な名前を入力してください。
他のCognito利用者と重複できないので、誰も使っていそうもない値にします。
AWS Congnitoのユーザープールを利用したサインアップ
それでは、さっそく、サインアップしてみます。サインアップとはユーザ登録のことです。
これまで設定してきた内容が、どういう意味をもっていたのか、実際にサインアップを通してみていきます。
その前に、作成予定のWebアプリを立ち上げます。まずは暫定でよいので、「AWS Cognitoアプリクライアントの作成」のところで示したように、とりあえず https://localhost:3001/ を立ち上げます。
Node.jsをお使いであれば、とりあえず以下の感じです。
> mkdir simple-web-server
> cd simple-web-server
> npm init
> npm install express -–save
> npm install cors –-save
> mkdir cert
> mkdir public
> vi index.js
以下、index.js。
var express = require('express');
var app = express();
var cors = require('cors');
app.use(cors());
app.use(express.static('public'));
app.get('/', (req, res) =>{
res.send('Welcome to Express!<br>' + 'QueryString:' + JSON.stringify(req.query) );
});
app.listen(3000, () =>{
console.log('HTTP Server(3000) is running.');
});
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./cert/server.key'),
cert: fs.readFileSync('./cert/server.crt')
};
var server = https.createServer(options, app);
server.listen(3001, () =>{
console.log('HTTPS Server(3001) is running.');
});
HTTPSを使う場合は、certフォルダにSSL証明書を置いてください。
使わない場合は、var httpsの行以降をコメントアウトしてください。
これで、ポート3000にWebサーバが立ち上がりました。
HTTPSも有効にしている場合は、ポート3001に立ち上がっています。
もし、express-generatorを使ってひな型を作った場合は、bin/wwwの以下の行の後に、
/**
* Listen on provided port, on all network interfaces.
*/
server.listen(port);
server.on('error', onError);
server.on('listening', onListening);
以下を追加します。
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./cert/server.key'),
cert: fs.readFileSync('./cert/server.crt')
};
var servers = https.createServer(options, app);
servers.listen(port + 1); /* HTTPポートの+1をHTTPSポートにする */
servers.on('error', onError);
servers.on('listening', onListening);
試しに、ブラウザから以下のURLを打ち込んでみます。
https://localhost:3001/
今後、いろんなところでHTTPS接続を要求されますので、以降はHTTPS接続で進めます。
準備が整いました。
それでは、ブラウザから以下のURLを入力し、表示させてみます。
- ドメイン名:AWS Cognitoのドメイン名のページで指定したドメイン名
- アプリクライアントID:アプリクライアントのページで生成されたアプリクライアントID
- リダイレクト先URL:アプリクライアントの設定でとりあえず指定したコールバックURL(https://localhost:3001/)
※リダイレクト先URLは、最後のスラッシュ「/」も含め厳密に一致確認していますので正確に入力します。
こんな感じで、ログインページが表示されます。
AWS Cognitoが、デフォルトでログインページのひな型を用意してくれています。
もし、見かけを変えたい場合は、以下でカスタマイズできます。
AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「UIのカスタマイズ」を選択します。
まだ、ユーザ登録していないため、「Need an account? Sign up」からサインアップしてみます。
そうすると、「E メールまたは電話番号の検証を要求しますか?」でEメールを選択していた場合は、検証コード(Verification Code)の入力が促されます。サインアップ画面で入力したメールアドレスにメールが届いているはずですので、そのメールに書いてある検証コード(数字で6桁)を入力します。
これで、ユーザ登録と、Eメールの検証が完了し、アプリクライアントのWebページにリダイレクトされます。そのとき、QueryStringとしてcodeに認可コードがもらえます。
あとは、この認可コードを使って、以下のトークンエンドポイントからトークンを取得すればよいです。
https://<ドメイン名>.auth.ap-northeast-1.amazoncognito.com/oauth2/token
認可コードとはなんぞや、といった話は、OpenID Connectの用語なので、いったん横に置いておきます。
それでは、AWSマネージドコンソールから、登録されたユーザ情報を確認してみます。
AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「ユーザーとグループ」を選択します。
さきほどサインアップしたユーザが登録されているのがわかります。
Googleアカウントの連携を有効にする
すでにここまでで、へとへとですが、ここからようやく外部のソーシャルIDとの連携の設定ができるようになりました。
Google Cloud Platformを開きます。
開発者アカウントがない場合は、作る必要があります。
また、プロジェクトをまだ作成していない場合は、プロジェクトを作成し、左のリストから、「APIとサービス」を選択したのち、左側のリストから、「認証情報」を選択します。
まだ、「OAuth同意画面」タブの入力が済んでいない場合は入力しておきます。
さて、ここからが本題です。
「認証情報」タブを選択し、「認証情報を作成」します。
作成対象としてOAuthクライアントIDを選択し、以下を入力します。
- アプリケーションの種類:ウェブアプリケーション、
- 名前:任意(たとえば、Cognito Test)
- 認証済みのリダイレクトURI:https://<ドメイン名>.auth.ap-northeast-1.amazoncognito.com/oauth2/idpresponse
ここで生成された「クライアントID」と「クライアントシークレット」は後で使います。
さて今度は、AWSマネージドコンソールに戻って、さきほど生成した「クライアントID」と「クライアントシークレット」をAWS Cognitoに設定します。
AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「IDプロバイダ」を選択します。
「ユーザーに外部フェデレーテッド ID プロバイダ経由のサインインを許可しますか?」という画面が表示されます。
ここにはいくつかの外部ソーシャルIDが並んでいますが、その中に「Google」がありますのでそれを選択します。
ここで、「GoogleアプリID」にさきほどの「クライアントID」を、「アプリシークレット」に「クライアントシークレット」を転記します。「承認スコープ」には、「profile email openid」を指定します。emailを含めているのは、ユーザープール「test-pool」ではユーザ登録にEメールアドレスを必須としたためです。
最後に「Googleの有効化」ボタンを押下します。
ここで忘れずにしておく必要があるのは、「属性マッピング」です。
せっかくEメールアドレスをGoogleから取得するのにAWS Cognitoのユーザープールに取り込むようにしないといけません。
Google属性のemailを選択し、ユーザープール属性として「Email」を選択します。最後に「変更の保存」ボタンを押下します。
さらに、忘れてはいけないのは、「アプリクライアントの設定」です。
有効なIDプロバイダとして、「Google」が増えていますので、それも選択します。
AWS CongnitoのGoogleユーザのサインアップ
もう一度、ログイン画面を開いてみます。
今度は、Username/Password、Sign upの選択に加えて、左側にGoogleによるログインボタンが増えています。
押下するとGoogleログイン画面が現れ、Googleにログインすると、無事にWebアプリにログイン結果が戻ってきたのがわかります。
AWS Cognitoのユーザープール「test-pool」のログインユーザのリストを確認してみます。
Googleという接頭辞が付いたユーザが増えているのがわかります。
Googleユーザは、Googleにて本人確認が済んでいるため、検証コードによる検証はありません。
LINEアカウントの連携を有効にする
さあ、いよいよLINEアカウントの連携を有効にします。
ここに来るまですごく長く感じました。
まずは、LINEデベロッパーコンソールのページを開きます。
まだデベロッパーアカウントを持っていない場合は、ユーザ登録してログインします。
そこから、「LINEログインを始める」ボタンを押下します。
はじめてここに来た時には、プロバイダを作成していない状態のため、まずはプロバイダを作成しておきます。たとえば、名前を「Hello, LINEID」とでもしておきます。
これから左側から「Channel基本設定」「アプリ設定」をそれぞれ設定していきます。
「Channel基本設定」から。
アプリタイプとして「WEB」を選択しておきます。
メールアドレスは、念のため設定しておきます。(設定しない状態に戻せなかったため、これが必須なのかわかりませんでした。。。)
同じページに「Channel ID」と「Channel Secret」が生成されているので、覚えておきます。後で使います。
次は、「アプリ設定」。
リダイレクト設定として、以下のURLを設定します。
https://<ドメイン名>.auth.ap-northeast-1.amazoncognito.com/oauth2/idpresponse
今度はAWSマネージドコンソールに戻って、さきほど生成された「Channel ID」と「Channel Secret」をAWS Cognitoに設定します。
AWS Cognitoのページから、ユーザープール管理⇒「test-pool」⇒「IDプロバイダ」を選択します。
LINEは、OpenID Connectに準拠しているため、ここでは「OpenID Connect」を選択します。
それぞれ以下の通り入力します。
プロバイダ名:任意(ここでは、LINE)とします。
- クライアントID:さきほど覚えておいた「Channel ID」を入力します。
- クライアントのシークレット(オプション):さきほど覚えておいた「Channel Secret」を入力します。
- 属性のリクエストメソッド:GET
- 承認スコープ:profile email openid
- 発行者:https://access.line.me
ここで、上記を入力して「検出の実行」ボタンを押下しても失敗してしまいます。
そこで、さらに以下を入力します。
- 認証エンドポイント:https://access.line.me/oauth2/v2.1/authorize
- トークンエンドポイント:https://api.line.me/oauth2/v2.1/token
- ユーザ情報エンドポイント:https://api.line.me/v2/profile
- Jwks uri:不明 (対象鍵による署名だからいらないのかな???)
(2020/09/01 追記)
Jwks uri のところは何かしら入力しないとエラーとなるので、適当に https://api.line.me/oauth2/v2.1/verify とでも入れておきましょう。
(2022/6/24 追記)
最近だと、スコープに emailを指定する場合は、「メールアドレスの取得権限」も申請する必要があるようです。
https://developers.line.biz/ja/docs/line-login/integrate-line-login/#applying-for-email-permission
Googleの時と同様に、「属性マッピング」を設定します。
設定したLINEは、「OIDC」にあります。
そこで、OIDC属性の追加、OIDC属性としてemail、ユーザープール属性として「Email」を選択し、「変更の保存」ボタンを押下します。
そして、「アプリクライアントの設定」から、有効なIDプロバイダとして、さきほど作成した「LINE」を選択し、「変更の保存」ボタンを押下します。
AWS CongnitoのLINEユーザのサインアップ
いよいよ、LINEユーザでAWS Cognitoにログインしてみます。
ログインURLをブラウザに入力すると、今度はGoogleログインボタンの上に、「LINE」ログインボタンが現れました。
押下すると、途中、以下のようなLINEユーザログイン画面が表示されてログインした後、
ユーザ情報としてメールアドレスのアクセス要求の確認画面が表示されます。
無事に、Webアプリに画面が戻ってきました。
AWS Cognitoのユーザープール「test-pool」のログインユーザのリストを確認してみます。
LINEという接頭辞が付いたユーザが増えているのがわかります。
Googleの時と同様、LINEユーザは、検証コードによる検証はありません。
YahooIDアカウントの連携を有効にする
YahooIDも頑張ってみました。
- Yahoo!デベロッパーネットワーク
まずは、上記にユーザ登録してログインします。
たくさんの機能を提供していますが、いくつかある機能のうち、「ID連携」が、OpenID Connectに該当します。
ID連携には、いくつかの種類のバージョンがあるようで、「Yahoo! ID連携 v2」を使います。
ここから、アプリケーションの登録を行います。
登録が完了すると、以下のような画面が表示されます。
このうち、「Client ID」と「シークレット」を使います。
コールバックURLには以下を指定しておきます。
https://<ドメイン名>.auth.ap-northeast-1.amazoncognito.com/oauth2/idpresponse
今度は、AWS Cognitoの設定の方です。
以下に、IDプロバイダの設定値を示しておきます。
- プロバイダ名:任意(たとえばYahooID)
- クライアントID:さきほど記録した「Client ID」
- クライアントのシークレット(オプション):さきほど記録した「シークレット」
- 属性のリクエストメソッド:GET
- 承認スコープ:profile email openid
- 発行者:https://auth.login.yahoo.co.jp/yconnect/v2
そして、「検出を実行」ボタンを押下して、最後に「プロバイダの作成」ボタンを押下します。
このあたりからは、GoogleやLINEアカウントを設定したときと同じような流れになります。
同様に、「属性マッピング」を設定します。設定したYahooIDは、「OIDC」にあります。
そこで、OIDC属性の追加、OIDC属性としてemail、ユーザープール属性として「Email」を選択し、「変更の保存」ボタンを押下します。
そして、「アプリクライアントの設定」から、有効なIDプロバイダとして、さきほど作成した「YahooID」を選択し、「変更の保存」ボタンを押下します。
ログインURLをブラウザに入力すると、今度はGoogleやLINEログインボタンの上に、「YahooID」ログインボタンが現れました。
YahooIDのログイン画面が表示されます。
問題なければログインに成功するはずです。
AWS Cognitoのユーザープール「test-pool」のログインユーザのリストを確認してみます。
YahooIDという接頭辞が付いたユーザが増えているのがわかります。
GoogleやLINEの時と同様、YahooIDユーザは、検証コードによる検証はありません。
(ご参考)
AWS IAMに、OpenID Connectを登録して、AWS Cognito フェデレーティッドアイデンティティーで連携させる方法もあるようです。
CognitoでOpenID Connect(Yahoo! ID連携) - Qiita
追記
私の投稿にいただいている「いいね!」はだいたい数件なのですが、なぜかこの投稿だけ二桁多いんです。(もちろんありがたいです。)
ソーシャルアカウント連携ってやっぱり需要はあるんでしょうか。もしCognitoにもご興味を持っているのであれば、以下の投稿もしてますので、よろしければこちらもどうぞ。
AWS Cognitoにサインインしないと見れないLambdaを作る
AWS Cognitoのカスタム認証フローを使って合言葉認証を作る
AWS CognitoでClient Credentials Grantを使ってみる
AWS CognitoとAWS IoTを連携させてみる
AWS CognitoとAWS IoTを連携させてみる(パート2)
AWS Cognitoのエンドポイントを使いこなす
AWS Cognitoで認証しないと呼び出せない何かのサーバを作る
AWS CognitoとなんちゃってOpenID ConnectサーバをIDフェデレーションする
AWS Cognitoの画面遷移しないサインインページを作る
AWS CognitoにAndroidネイティブアプリでサインインする
AWS CognitoにLogin with Amazonアカウントを追加する
以上