AWS
DynamoDB
lambda
APIGateway

ログイン・ログアウト機能をサーバレスアーキテクチャで実装する

More than 1 year has passed since last update.


本記事を読む前の注意事項

現在ではAWSにUser Poolsという機能があります。

そちらを利用してログイン・ログアウトを実装したほうが遥かに効率が良いです。Amazon Cognito User Poolsを使って、webサイトにユーザ認証基盤を作るをご参照ください


概要

会員登録機能をサーバレスアーキテクチャで実装する に引き続き、今度はログイン・ログアウトの機能をAWSで構成を組みます。


アーキテクチャ

ログイン・ログアウト.png


テーブル構成

DynamoDBでテーブルを構成します。


Usersテーブル

ユーザ情報を格納するテーブルです。ログインフォームからの情報を付きあわせて認証を行います。

項目
制約
備考

email
Hash key
会員IDとなるメールアドレスを保存

password

パスワード

※実運用ではパスワードは暗号化して保存しましょう。また、登録日などの項目も運用次第で必要になると思います。


Sessionテーブル

セッション情報を格納するテーブルです。ログインが成功したら発行したセッションIDをこのテーブルに書き込み、ユーザのログイン、ログアウトの状態を管理します。

項目
制約
備考

 session_id
Hash key
セッションID

email

Usersテーブルとの付き合わせ用

※実運用では、登録日などの項目も持たせて、セッションタイムアウト時間も設けたほうが良いです。


Lambdaファンクション


ログイン処理

入力値として、emailとパスワードを受け取ります。

ログインに成功すればセッションIDを返します。webシステムで使う場合はこのセッションIDをcookieに保存して引き回してあげましょう


login.js

var aws = require("aws-sdk");

var doc = require('dynamodb-doc');
var crypto = require('crypto');
var dynamo = new doc.DynamoDB();

exports.handler = function(event, context) {

if ( typeof event.email === 'undefined' || typeof event.password === 'undefined' ) {
context.fail("Login failed");
}

if ( event.email === '' || event.password === '' ) {
context.fail("Login failed");
}
console.log(event.email);
var dynamoRequest = {
TableName: 'users',
Key: {
"email": event.email
}
};

dynamo.getItem(dynamoRequest, function (err, res) {

if (err) {
console.log(err);
return;
} else {
console.log(event.email);
console.log(res);
if ( Object.keys(res).length > 0 && res.Item.password === event.password ) {
var date = new Date() ;
var session_id = md5_hex(date.getTime() + event.email);
var dynamoRequest = {
TableName: 'session',
Item: {
'session_id':session_id,
'email':event.email
}
};

dynamo.putItem(dynamoRequest, function(err, data){
if (err) {
console.log(err);
} else {
context.succeed({session_id:session_id});
}
});

} else {
context.fail("Login failed");
}
}
});
};

function md5_hex(src) {
var md5 = crypto.createHash('md5');
md5.update(src, 'utf8');
return md5.digest('hex');
}



ログアウト処理

入力値としてセッションIDを渡して、Sessionテーブルからレコードを削除します。


logout.js

var aws = require("aws-sdk");

var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();

exports.handler = function(event, context) {
var dynamoRequest = {
TableName: 'session',
Key: {
"session_id": event.session_id
}
};

dynamo.deleteItem(dynamoRequest, function (err, res) {
if (err) {
console.log(err);
return;
} else {
context.succeed({ret:'true'});
}
});
}



API Gateway

上記のLambdaファンクションをAPIとして設定してあげます。


webシステムをフロントとして組み込む

S3においたHTML上でJavaScriptからこれらのAPIを叩いてシステム化を行います。

ログイン処理はこんな感じでAjaxで行います。ちなみにjQueryで書いてます

$("#login").on( "click", function(){

var data = {
email:$("#email").val(),
password:$("#password").val()
}
$.ajax( {
url:'<API Gatewayエンドポイント>',
method: "POST",
crossDomain: true,
data: JSON.stringify(data),
success: function(response) {
if ( typeof response.session_id !== 'undefined' ) {
$.cookie("serverless_website_session_id", response.session_id, {path:"/"});
location.href = "/mypage";
} else if ( response.errorMessage === 'Login failed' ) {
$('#error').text('Login failed');
}
}
});

こんな感じで実装が行えました。

スクリーンショット 2016-04-14 8.42.19.png

スクリーンショット 2016-04-14 8.42.30.png