はじめに
Cognitoのユーザ属性にカスタム属性として「セーブ数」を登録して、管理者が許可したらその属性を修正し、アプリ側でカスタム属性を取得したいなぁ…と思ったら案外めんどくさかった、という話。
まとめると
・AWS管理コンソールから属性の値を登録することも更新することもできない(と思う)。
・でもAPIからなら普通に更新ができる。
・値も普通に取得できる。
ユーザのカスタム属性の値を修正したいんですけど
ユーザを初期登録するときには設定できる。
でも修正ができない。
管理コンソールに修正するところがあるんじゃないか?と思って眺めても…ない。
ネットを調べてもない。
Userpool自体の初期登録の仕方なのか?と思ったがそうでもない様子。
そもそもカスタム属性は初期登録時のみなのか??
メソッド名に「adminUpdateUserAttributes」なんてのがあるんだから更新できるんじゃないの?
と思って、せめてAPI経由でも更新させてくれよーと思ったら…
awsのフォーラムにありました。
var AWS = require('aws-sdk');
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
exports.handler = (event, context, callback) => {
var params = {
UserAttributes: [ / required /
{
Name: 'custom:attributename', / required /
Value: 'value'
},
/ more items /
],
UserPoolId: 'ap-southeast-2_abcdefghi', / required /
Username: 'username'/ required /
};
cognitoidentityserviceprovider.adminUpdateUserAttributes(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};
なるほどできるんだなぁ…と思って、やってみた。
/required/
ってコメントは抜かないとエラーになるんだなぁ…
var AWS = require('aws-sdk');
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
exports.handler = (event, context, callback) => {
var params = {
UserAttributes: [
{
Name: 'custom:SavePoint',
Value: '2'
},
],
UserPoolId: 'ap-northeast-1_hohohoho',
Username: 'hoge'
};
cognitoidentityserviceprovider.adminUpdateUserAttributes(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
};
これだけだとアクセス権とか大丈夫なのか?と思ったら案の定ロール定義が必要だった。
ロール定義するためにはポリシー定義が必要でした。
必要なポリシーは「cognito User Pools」のみ。
そのポリシーと新しく作ったロールを関連付ける。
そして、上記関数のロールにする。
実行すると…案外素直に動きました。
カスタム属性はnumber型なのですが、valueの指定は''を付けるんだね。
値が変わったことは画面から確認できる。
なお、もともと値が登録されてなくてもadminUpdateUserAttributesを使えば登録できる。
値の取得
これもまた微妙に面倒…
日本語で書かれたチュートリアルがあるのだが、なんだかわかりにくい。
結局[SDKのサンプル]
(https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html#getUser-property)をみて作成した。
AWS.config.update({
accessKeyId: 'XXXXXXXXX', //IAMのアクセスキーID
secretAccessKey: 'YYYYYYY', //アクセスキーID作成時のみ表示
region:'ap-northeast-1',
IdentityPoolId: 'ap-northeast-1:XX-XXXX-xxxx-xxxx-xx'
});
(signin処理は省略:signin時にアクセストークン取得できる。)
var SavePoint = 0;
var cognitoSP = new AWS.CognitoIdentityServiceProvider({apiVersion: '2016-04-18'});
cognitoSP.getUser({AccessToken:data.AuthenticationResult.AccessToken},function(err,data){
if(err) console.log(err,err.stack);
else {
data.UserAttributes.forEach(function(val,id,arary) {
if (val.Name == 'custom:SavePoint') {
SavePoint = val.Value;
}
});
}
});
途中の「data.AuthenticationResult.AccessToken」にはアクセストークンを入れる必要がある。
アクセストークンはsignin時に取得できる。(ここでは途中端折ってる)
これでSavePointにcognitoのカスタム属性(custom:SavePoint)の値が入りました。
最後に
案外簡単なのはわかったが、ここまで来るのに4時間ぐらいかかった。
値の変更を画面からでも追加、修正できるようになればもう少し簡単になるのだけど。