はじめに
この記事は初めてのAuth0ハンズオンとAuth0のユニークな機能 - Linking User Accounts編その1の続編で、Auth0のユニークな機能の一つであるLinking User Accountsの応用編です。Auth0のManagement APIで公開しているEnd Pointにhttpリクエストを送信してアカウントをリンク・アンリンクしてどのような挙動をするか確認しています。
検証
リンク
同じEmail Addressを持っているGoogleとFacebookのアカウントでリンクしてみます。Management APIにPostリクエストを送信してGoogleとFacebookのアカウントをリンクします。

Auth0 Dashboardの左ペイン”APIs”をクリック、”Auth0 Management API”を選択して"API Explorer"タブをクリックして”Token”をクリップボードにコピーします。
このTokenはManagement APIへのフル権限を持ったTokenです。このTokenをManagement APIのドキュメントにセットしてダイナミックなcurlコマンドを作成します。

Management API左上の"SET API TOKEN"をクリックしてクリップボードにコピーしたTokenをペーストして”SET TOKEN”を押します。

/api/v2/users/{id}/identities End PointにPostリクエストを送信するcurlコマンドを生成します。

"id"にはPrimary Providerアカウントのuser_idを指定します。例 : google-oauth2|109026600466545709878
"body"にはSecondary ProviderアカウントのProviderとuser_idを指定します。以下、例です。
{
"provider": "facebook",
"user_id": "2139237436182114"
}
"get curl command"をクリックして生成されたコマンドをターミナルにコピーペーストして実行します。
$ curl -H "Authorization: Bearer eyJhxxxx" -X POST -H "Content-Type: application/json" -d '{"provider":"facebook","user_id":"2139237436182114"}' https://pannacotta.auth0.com/api/v2/users/google-oauth2%7C109026600466545709878/identities
Dashboard左ペインの"Users & Roles"->"Users"をクリックしてアカウントがリンクされていることを確認します。アカウントをクリックして”Row JSON"タブをクリック、リンクされたJSONを確認します。

{
"created_at": "2020-01-25T03:47:12.864Z",
"email": "cookiewanwan@gmail.com",
"email_verified": true,
"family_name": "Yamaguchi",
"given_name": "Hisashi",
"identities": [
{
"provider": "google-oauth2",
"user_id": "109026600466545709878",
"connection": "google-oauth2",
"isSocial": true
},
{
"profileData": {
"name": "Hisashi Yamaguchi",
"email": "cookiewanwan@gmail.com",
"given_name": "Hisashi",
"family_name": "Yamaguchi",
"picture": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=2139237436182114&height=50&width=50&ext=1582516018&hash=AeT52yBpX6StcIp0",
"picture_large": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=2139237436182114&width=999999&ext=1582516018&hash=AeSGejrtfDA7-Ovc",
"name_format": "{first} {last}",
"short_name": "Hisashi Yamaguchi",
"installed": true,
"install_type": "UNKNOWN",
"security_settings": {
"secure_browsing": {
"enabled": true
}
},
"video_upload_limits": {
"length": 14460,
"size": 28633115306
},
"viewer_can_send_gift": false,
"email_verified": true
},
"user_id": "2139237436182114",
"provider": "facebook",
"connection": "facebook",
"isSocial": true
}
],
"locale": "ja",
"name": "Hisashi Yamaguchi",
"nickname": "cookiewanwan",
"picture": "https://lh3.googleusercontent.com/a-/AAuE7mDS46tGHm2lQW8iHqYTC_Cgv0DtKCqGT88IUBiAoA",
"updated_at": "2020-01-25T04:01:05.164Z",
"user_id": "google-oauth2|109026600466545709878",
"last_ip": "126.233.110.117",
"last_login": "2020-01-25T03:49:43.857Z",
"logins_count": 4,
"blocked_for": [],
"guardian_authenticators": []
}
アンリンク
リンクしたアカウントをアンリンクします。/api/v2/users/{id}/identities/{provider}/{user_id} End PointDeleteリクエストを送信するcurlコマンドを生成します。
"id"にはプライマリアカウントのuser_id(例/google-oauth2|109026600466545709878)、"provider"はセカンダリアカウントのProviderを選択します。"user_id"はセカンダリアカウントのid(例/2139237436182114)を選択します。

"get curl command"をクリックして生成されたコマンドをターミナルにコピーペーストして実行します。
$ curl -H "Authorization: Bearer eyJhxxxx" -X DELETE https://pannacotta.auth0.com/api/v2/users/google-oauth2%7C109026600466545709878/identities/facebook/2139237436182114
Dashboard左ペインの"Users & Roles"->"Users"をクリックしてアカウントがアンリンクされていることを確認します。アカウントをクリックして”Row JSON"タブをクリック、各々のアカウントのJSONを確認します。

{
"created_at": "2020-01-25T04:53:39.295Z",
"email": "cookiewanwan@gmail.com",
"email_verified": true,
"family_name": "Yamaguchi",
"given_name": "Hisashi",
"identities": [
{
"provider": "google-oauth2",
"user_id": "109026600466545709878",
"connection": "google-oauth2",
"isSocial": true
}
],
"locale": "ja",
"name": "Hisashi Yamaguchi",
"nickname": "cookiewanwan",
"picture": "https://lh3.googleusercontent.com/a-/AAuE7mDS46tGHm2lQW8iHqYTC_Cgv0DtKCqGT88IUBiAoA",
"updated_at": "2020-01-25T04:57:03.493Z",
"user_id": "google-oauth2|109026600466545709878",
"last_ip": "126.233.110.117",
"last_login": "2020-01-25T04:53:39.293Z",
"logins_count": 1,
"blocked_for": [],
"guardian_authenticators": []
}
{
"created_at": "2020-01-25T04:57:03.504Z",
"email": "cookiewanwan@gmail.com",
"email_verified": true,
"family_name": "Yamaguchi",
"given_name": "Hisashi",
"identities": [
{
"user_id": "2139237436182114",
"provider": "facebook",
"connection": "facebook",
"isSocial": true
}
],
"install_type": "UNKNOWN",
"installed": true,
"name": "Hisashi Yamaguchi",
"name_format": "{first} {last}",
"nickname": "cookiewanwan",
"picture": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=2139237436182114&height=50&width=50&ext=1582520028&hash=AeTSH7GmePNsGvwn",
"picture_large": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=2139237436182114&width=999999&ext=1582520028&hash=AeT883zuqfADtrs3",
"security_settings": {
"secure_browsing": {
"enabled": true
}
},
"short_name": "Hisashi Yamaguchi",
"updated_at": "2020-01-25T04:57:03.504Z",
"user_id": "facebook|2139237436182114",
"video_upload_limits": {
"length": 14460,
"size": 28633115306
},
"viewer_can_send_gift": false,
"blocked_for": [],
"guardian_authenticators": [
{
"id": "recovery-code|dev_9PC19jCFChrstsGC",
"type": "recovery-code",
"confirmed": false,
"created_at": "2020-01-24T01:25:01.000Z"
},
{
"id": "totp|dev_Wa4yTOU6gGWs1LKB",
"type": "totp",
"confirmed": false,
"created_at": "2020-01-24T01:25:01.000Z"
}
]
}
おわりに
Auth0はJSONオブジェクトでユーザ属性を管理しており、柔軟にアカウントをリンク・アンリンクすることができます。リンクされたSecondary Providerのアカウントが持っていたJSONオブジェクトは物理的にDatabase上から削除され、アンリンクされたタイミングで再度JSONオブジェクを作成しています。物理削除なのでストレージスペースを節約できて検索性能の劣化も回避できますね。