自分が作るアプリの中でユーザー認証/登録といった機能が必要な場合、自分の場合は自作することはほとんどなく、IDaaS 等と呼ばれている SaaS 系専用サービスを使って実装しています。具体的には(資料が充実しているという理由ですが) Auth0 や AppID を使うことが多いです。単なるユーザー認証だけでなく、(実装する場合に面倒な)オンラインサインアップやパスワード再設定、パスワード忘れ時のリセット機能などをサービスが既にセキュアな形で組み込まれていて、自分ではほぼ実装を意識することなく使えて便利※です。
※もう少しちゃんと説明すると、Auth0 の場合であれば認証自体は OAuth を使って auth0.com で行い、認証情報が正しければコールバックで受け取った情報を使ってアクセストークンを取得できる、というロジックを簡単に実装できます。
この Auth0 を使ってアプリを作った場合、ユーザー名(表示名)やそのアイコン画像は(特定のルールに基づいて)登録時に決まります。ユーザー名はともかく、特にアイコン画像は自動生成されたものではなく自分で気に入っているものを使いたいと感じることが多いと思っています。が、現状ユーザー本人が直接変更することはできません。登録時に決まったものを使い続ける、ということになるので、こだわりを持ったユーザー名やユーザーアイコンへの変更ができないことを問題と感じていました。
で、Auth0 を調べたところ「変更用の API 自体は提供されている」ことが分かりました。要はユーザーが直接変更する機能は提供されていないが、その機能を自分で自分のアプリ内に作る方法は提供されている、ということになります。これを Node.js で早速試してみたのが今回のブログエントリのテーマです。
【プロフィール画像変更 API】
例えばプロフィール画像を変更する API 自体はこのように提供されています(下図は Node.js のサンプル):
この上図で言うところの USER_ID 部分に画像を変更したいユーザーの ID(Auth0 上での User.id)を指定し、また変更後の画像 URL を picture の値として指定した上で上述の REST API を実行すればよい、ということになります。
特に Node.js の場合は同様の処理をより簡単に実行できるような SDK も提供されており、こちらを使った場合は ManagementClient クラスの update メソッドに必要なパラメータを渡して実行するだけです。
なおどちらの例もユーザーのアイコン画像(picture)だけを変更する例として紹介されていますが、実際には picture 以外にも nickname(表示名)や firstName, lastName など他の多くの属性を変更することも可能です。 実装そのものは後者(SDK)の方が簡単なので、以下こちらを使って説明を続けます。
【client_id と client_secret の準備】
この API を実行するには Auth0 の認証アプリを作る時と同様に client_id と client_secret (と domain)情報が必要です。ただ多くの場合、取得し直しが必要になる点に注意が必要です。以下は Auth0.com にログインし、メニューから Applications - Applications を選択した後に "Create Application" を実行した時の画面です:
Auth0 を使って自分のアプリに認証機能を付加する場合、そのアプリの種類によって "Native(スマホ向けネイティブアプリ)", "Single Page Web Application(SPA)", "Regular Web Applications(その他のいわゆる「ウェブアプリ」)" のいずれかから1つ選んで(Auth0 の)アプリケーションを登録することが多いはずです:
ですが、今回の機能を実現するためには "M2M(Machine to Machine)Applications" の client_id と client_secret が必要になります。そのため、まだ M2M アプリを作ったことがない場合は Machine to Machine Applications を選択して、新たに1つ追加登録してください:
次の画面で対象 API を選択しますが、M2M アプリの場合は "Auth Management API" の1つしか選択肢がないので、これを選択します:
最後に API の許可スコープを指定します。今回はユーザー管理機能を実装するので、検索バーに "users" と入力し、そこで見つかる全てのスコープにチェックを入れて、最後に "Authorize" ボタンをクリックするとアプリケーション登録が完了します:
こうして Auth0.com に作成(追加)した M2M アプリケーションの Client ID、Client Secret(と Domain ですが、Domain は他のアプリ登録時に取得したものと同じはずです)が必要になります。利用時にすぐ取得できるようコピー&ペースト等で準備しておいてください:
【実装】
ここまでの準備ができたら実装してみましょう。Node.js の場合は auth0 という便利なクライアントライブラリの SDK があるので、これを使って実装します。なお最後にサンプルアプリ・ソースのリンクを載せておくので、興味ある方はそちらをダウンロード後に実際に動作確認してみてください。
まず auth0 をインスタンス化します:
auth0 の ManagementClient を取得し、domain, client_id, client_secret の3つの値と、スコープとして 'create:users read:users update:users' を指定してインスタンス化します(今回はプロフィール画像 URL を更新するため、これら全てがスコープとして必要になります)。繰り返しになりますが、重要なのはここで指定する client_id や client_secret は通常のネイティブアプリケーション/ウェブアプリケーションのものではなく、M2M アプリケーションとして登録したアプリケーションのものを使う必要がある、という点です。
そして実際に user_id = 'abcabc' のユーザーのプロフィール画像 URL を変更する場合は、以下のような処理を行います:
実行する関数は auth0.users.update() で、この実行時パラメータとして第一パラメータに対象ユーザーの情報、第二パラメータに変更内容を指定します。実行後にエラーか成功かを識別して処理を続けます。
上の例だとプロフィール画像だけを変更していますが、複数の属性を同時に変更することも可能です。例えば以下の例は対象ユーザーのプロフィール画像(picture)と表示名(nickname) を同時に変更しています:
参考になれば、と思って実際に動くサンプルアプリを用意しました:
https://github.com/dotnsf/auth0-userpicture
サンプルアプリを実際に動かす場合は Auth0 に(M2M ではない通常の Web)アプリケーションも登録し、その client_id, client_secret, domain を取得し、また OAuth のコールバックURL(callback_url) を実行時の環境変数に登録する必要があります。実行時の環境変数登録時は同リポジトリ内の .env ファイルにその内容を記載することでも代替可能です。
参照していただくとわかるのですが、実際にユーザーの属性を変更しようとすると対象ユーザーの ID が必要になります。ユーザー ID は OAuth でログイン後にわかるので、実際のアプリケーションでは普通の(通常のウェブの)アプリケーションと、ユーザー管理用の M2M アプリケーションの2つを登録する必要があり、それぞれの client_id と client_secret の両方を使って実装することになります。詳しくはソースコード内を参照ください。
※もう少しちゃんと説明すると、Auth0 の場合であれば認証自体は OAuth を使って auth0.com で行い、認証情報が正しければコールバックで受け取った情報を使ってアクセストークンを取得できる、というロジックを簡単に実装できます。
この Auth0 を使ってアプリを作った場合、ユーザー名(表示名)やそのアイコン画像は(特定のルールに基づいて)登録時に決まります。ユーザー名はともかく、特にアイコン画像は自動生成されたものではなく自分で気に入っているものを使いたいと感じることが多いと思っています。が、現状ユーザー本人が直接変更することはできません。登録時に決まったものを使い続ける、ということになるので、こだわりを持ったユーザー名やユーザーアイコンへの変更ができないことを問題と感じていました。
で、Auth0 を調べたところ「変更用の API 自体は提供されている」ことが分かりました。要はユーザーが直接変更する機能は提供されていないが、その機能を自分で自分のアプリ内に作る方法は提供されている、ということになります。これを Node.js で早速試してみたのが今回のブログエントリのテーマです。
【プロフィール画像変更 API】
例えばプロフィール画像を変更する API 自体はこのように提供されています(下図は Node.js のサンプル):
この上図で言うところの USER_ID 部分に画像を変更したいユーザーの ID(Auth0 上での User.id)を指定し、また変更後の画像 URL を picture の値として指定した上で上述の REST API を実行すればよい、ということになります。
特に Node.js の場合は同様の処理をより簡単に実行できるような SDK も提供されており、こちらを使った場合は ManagementClient クラスの update メソッドに必要なパラメータを渡して実行するだけです。
なおどちらの例もユーザーのアイコン画像(picture)だけを変更する例として紹介されていますが、実際には picture 以外にも nickname(表示名)や firstName, lastName など他の多くの属性を変更することも可能です。 実装そのものは後者(SDK)の方が簡単なので、以下こちらを使って説明を続けます。
【client_id と client_secret の準備】
この API を実行するには Auth0 の認証アプリを作る時と同様に client_id と client_secret (と domain)情報が必要です。ただ多くの場合、取得し直しが必要になる点に注意が必要です。以下は Auth0.com にログインし、メニューから Applications - Applications を選択した後に "Create Application" を実行した時の画面です:
Auth0 を使って自分のアプリに認証機能を付加する場合、そのアプリの種類によって "Native(スマホ向けネイティブアプリ)", "Single Page Web Application(SPA)", "Regular Web Applications(その他のいわゆる「ウェブアプリ」)" のいずれかから1つ選んで(Auth0 の)アプリケーションを登録することが多いはずです:
ですが、今回の機能を実現するためには "M2M(Machine to Machine)Applications" の client_id と client_secret が必要になります。そのため、まだ M2M アプリを作ったことがない場合は Machine to Machine Applications を選択して、新たに1つ追加登録してください:
次の画面で対象 API を選択しますが、M2M アプリの場合は "Auth Management API" の1つしか選択肢がないので、これを選択します:
最後に API の許可スコープを指定します。今回はユーザー管理機能を実装するので、検索バーに "users" と入力し、そこで見つかる全てのスコープにチェックを入れて、最後に "Authorize" ボタンをクリックするとアプリケーション登録が完了します:
こうして Auth0.com に作成(追加)した M2M アプリケーションの Client ID、Client Secret(と Domain ですが、Domain は他のアプリ登録時に取得したものと同じはずです)が必要になります。利用時にすぐ取得できるようコピー&ペースト等で準備しておいてください:
【実装】
ここまでの準備ができたら実装してみましょう。Node.js の場合は auth0 という便利なクライアントライブラリの SDK があるので、これを使って実装します。なお最後にサンプルアプリ・ソースのリンクを載せておくので、興味ある方はそちらをダウンロード後に実際に動作確認してみてください。
まず auth0 をインスタンス化します:
//. Auth0 Management API var ManagementClient = require( 'auth0' ).ManagementClient; var auth0 = new ManagementClient({ domain: 'xxxx.auth0.com', // domain の値 clientId: 'client_id', // client_id の値 clientSecret: 'client_secret', // client_secret の値 scope: 'create:users read:users update:users' });
auth0 の ManagementClient を取得し、domain, client_id, client_secret の3つの値と、スコープとして 'create:users read:users update:users' を指定してインスタンス化します(今回はプロフィール画像 URL を更新するため、これら全てがスコープとして必要になります)。繰り返しになりますが、重要なのはここで指定する client_id や client_secret は通常のネイティブアプリケーション/ウェブアプリケーションのものではなく、M2M アプリケーションとして登録したアプリケーションのものを使う必要がある、という点です。
そして実際に user_id = 'abcabc' のユーザーのプロフィール画像 URL を変更する場合は、以下のような処理を行います:
var params = { user_id: 'abcabc' }; // ユーザーIDが 'abcabc' の人が対象 var metadata = { picture: 'https://manholemap.juge.me/imgs/logo.jpg' }; // プロフィール画像を指定 URL のものに変更する auth0.users.update( params, metadata, function( err, user ){ if( err ){ console.log( { err } ); : // エラー時の処理 }else{ console.log( { user } ); : // 成功時の処理 } });
実行する関数は auth0.users.update() で、この実行時パラメータとして第一パラメータに対象ユーザーの情報、第二パラメータに変更内容を指定します。実行後にエラーか成功かを識別して処理を続けます。
上の例だとプロフィール画像だけを変更していますが、複数の属性を同時に変更することも可能です。例えば以下の例は対象ユーザーのプロフィール画像(picture)と表示名(nickname) を同時に変更しています:
var params = { user_id: 'abcabc' };
var metadata = { nickname: '俺', picture: 'https://manholemap.juge.me/imgs/logo.jpg' };
auth0.users.update( params, metadata, function( err, user ){
if( err ){
console.log( { err } );
:
}else{
console.log( { user } );
:
}
});
参考になれば、と思って実際に動くサンプルアプリを用意しました:
https://github.com/dotnsf/auth0-userpicture
サンプルアプリを実際に動かす場合は Auth0 に(M2M ではない通常の Web)アプリケーションも登録し、その client_id, client_secret, domain を取得し、また OAuth のコールバックURL(callback_url) を実行時の環境変数に登録する必要があります。実行時の環境変数登録時は同リポジトリ内の .env ファイルにその内容を記載することでも代替可能です。
参照していただくとわかるのですが、実際にユーザーの属性を変更しようとすると対象ユーザーの ID が必要になります。ユーザー ID は OAuth でログイン後にわかるので、実際のアプリケーションでは普通の(通常のウェブの)アプリケーションと、ユーザー管理用の M2M アプリケーションの2つを登録する必要があり、それぞれの client_id と client_secret の両方を使って実装することになります。詳しくはソースコード内を参照ください。