Amazon Cognitoを使ってNode.jsで認証
- 2019.11.16
- AWS
ユーザ認証を実装する際に、これからCognitoを使用する機会が多くなりそうなので試しに使ってみました。
今回は、CognitoのUser Poolsを使って認証の一連の流れを実装してみました(サインアップ→アクティベート→サインイン)。今回は実装しませんが、AWSリソースへのアクセス許可(認可)に関してはFederated Identitiesを使うみたいです。
目次
AWSマネジメントコンソールでの設定
ユーザプールを作成
- マネジメントコンソールからCognitoを開く
- 「ユーザプールを作成する」をクリック
- プール名を指定し「デフォルトを確認する」をクリックし、作成
アプリクライアントの作成
- サイドメニューから「アプクライアント」を選択
- アプリクライアント名を指定し、「クライアントシークレット作成」のチェックを外して作成
Node.jsのコーディング
まずは、Expressのインストール。
npm i express
続いて、以下をインストール。
npm i amazon-cognito-identity-js
npm i node-fetch
AuthController.jsとAuthService.jsを作成して、準備完了。
サインアップ
AuthService.js
※process.env.USER_POOL_ID、process.env.CLIENT_IDの箇所は、マネジメントコンソールで取得できる「プールID」、「アプリクライアントID」をそれぞれ入力します。
global.fetch = require('node-fetch')
const AmazonCognitoIdentity = require('amazon-cognito-identity-js')
const poolData = {
UserPoolId: process.env.USER_POOL_ID,
ClientId: process.env.CLIENT_ID,
}
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);
exports.Register = (body, callback) => {
const name = body.name;
const email = body.email;
const password = body.password;
const attributeList = [];
attributeList.push(new AmazonCognitoIdentity.CognitoUserAttribute({
Name: 'email',
Value: email
}))
userPool.signUp(name, password, attributeList, null, (err, result) => {
if (err) callback(err);
callback(null, result.user)
})
}
AuthController.js
const authService = require('./AuthService');
exports.register = (req, res) => {
authService.Register(req.body, (err, result) => {
if (err) res.send(err);
res.send(result)
})
}
上記で、サインアップのコーディングは完了。ルーティングなど指定して一旦挙動確認してみます。
routes.js
const express = require('express');
const router = express.Router();
const authController = require('./AuthController');
router.post('/auth/register', authController.register);
module.exports = router;
app.js
const express = require('express')
const app = express();
const routes = require('./routes');
app.use(express.json())
app.use(express.urlencoded({ extended: false }));
app.use('/', routes)
module.exports = app;
server.js
const app = require('./app')
var server = app.listen(3000, function () {
console.log('Server is runnning on port 3000')
})
ここまで記述したら、node server.js でサーバ起動するはず。
以下の形でAPIを叩くと、入力したメールアドレスにアクティベート用のコードが届く。
アクティベート
AuthService.js
exports.Activate = (body, callback) => {
const name = body.name;
const activateKey = body.key;
const userData = {
Username: name,
Pool: userPool
}
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.confirmRegistration(activateKey, true, (err, result) => {
if (err) callback(err);
callback(null, result)
})
}
AuthController.js
exports.activate = (req, res) => {
authService.Activate(req.body, (err, result) => {
if (err) res.send(err);
res.send(result)
})
}
サインイン
AuthService.js
exports.Login = (body, callback) => {
const name = body.name;
const password = body.password;
const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
Username: name,
Password: password
})
const userData = {
Username: name,
Pool: userPool
}
const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: result => {
const accessToken = result.getAccessToken().getJwtToken()
callback(null, accessToken)
},
onFailure: err => {
callback(err)
},
mfaRequired: function (codeDeliveryDetails) {
var verificationCode = prompt('Please input verification code', '');
cognitoUser.sendMFACode(verificationCode, this);
}
})
}
AuthController.js
exports.login = (req, res) => {
authService.Login(req.body, (err, result) => {
if (err) res.send(err);
res.send(result)
})
}
以上で終了。routes.jsは、最終的に下記のようになります。
routes.js
var express = require('express');
var router = express.Router();
var authController = require('./Controllers/AuthController');
router.post('/auth/register', authController.register);
router.post('/auth/activate', authController.activate);
router.post('/auth/login', authController.login);
router.post('/auth/activate', authController.activate);
module.exports = router;
APIを叩く際のパラメータなどは、コードの中から読み取ってください笑。
ログインAPIを叩くと、JWTトークンが取れます。
今回は一旦ここまで。
-
前の記事
Tensorflow.jsで手書き文字認識 2019.06.30
-
次の記事
SQSをトリガーにLambdaを起動(Serverless Framework) 2019.11.17