menu-icon

セッション管理にDynamoDBを使う

PHPアプリケーションのセッション管理に、NoSQLデータベースのAmazon DynamoDBを使ってみました。

準備

IAMユーザーのアクセスキー

DynamoDBにアクセスするためのIAMユーザーのアクセスキー(アクセスキー ID、シークレットアクセスキー)を用意します。今回はお試しなので細かい設定はせずに、AmazonDynamoDBFullAccessをアタッチしたユーザーを用意しました。

以下、awsコマンドはこのユーザーとして実行しています。またリージョンはus-west-2としています。

DynamoDBローカルのセットアップ

開発用にDynamoDBローカルをセットアップします。公式マニュアルによると、いくつか方法があるようですが今回はDockerを使用しました。

$ docker pull amazon/dynamodb-local
$ docker run -p 8000:8000 amazon/dynamodb-local

これでlocalhostの8000番ポートで接続できるようになります。

セッションデータ保存用のテーブル作成

セッションデータを保存するためのsessionsテーブルを作成します。キーはIDです。

$ aws dynamodb create-table --table-name=sessions --attribute-definitions AttributeName=id,AttributeType=S --key-schema AttributeName=id,KeyType=HASH --billing-mode PAY_PER_REQUEST --endpoint-url http://localhost:8000

これでDynamoDBの準備はできました。

アプリケーション

composer init後の状態から始めます。

まず、AWSのSDKをインストールします。

$ composer require aws/aws-sdk-php

次に実際にアクセスするPHPファイルを用意します。以下のtest.phpだけです。

sdataパラメータが渡されれば、値をセッションに保存します。sdataパラメータが渡されない場合、セッションに保存してある値を表示します。

なお、ユーザーの都合上、credentialsをハードコードしています。実際に使う場合はご注意ください。

test.php
<?php

require 'vendor/autoload.php';

use Aws\DynamoDb\SessionHandler;

$sdk = new Aws\Sdk([
    'endpoint'   => 'http://localhost:8000',
    'region'   => 'us-west-2',
    'version'  => 'latest',
    'credentials' => [
        'key' => 'YOUR_ACCESS_KEY',
        'secret' => 'YOUR_SECRET',
    ],
]);

$dynamo_db = $sdk->createDynamoDb();

$session_handler = SessionHandler::fromClient($dynamo_db);
$session_handler->register();

// Start the session
session_start();

if (isset($_GET['sdata'])) {
    // store
    $_SESSION['sdata'] = $_GET['sdata'];
    echo 'Stored';
} else {
    // receive
    if (isset($_SESSION['sdata'])) {
        echo 'Data : ' . $_SESSION['sdata'];
    } else {
        echo 'Not found';
    }
}

動かしてみる

test.phpにアクセスします。

セッションに保存してあるデータはありませんので、Not foundと表示されます。次にtest.php?sdata=hogehogeにアクセスします。

これでデータが保存されたはずです。もう一度test.phpにアクセスします。

先程、保存した'hogehoge'が表示されました。念のためDynamoDBのデータを直接確認してみます。

$ aws dynamodb scan --table-name sessions --endpoint-url http://localhost:8000
{
    "Items": [
        {
            "data": {
                "S": "sdata|s:8:\"hogehoge\";"
            },
            "expires": {
                "N": "1592059204"
            },
            "id": {
                "S": "PHPSESSID_mgi93nnshisagp96ch41bgpmeq"
            }
        }
    ],
    "Count": 1,
    "ScannedCount": 1,
    "ConsumedCapacity": null
}

このようにdata属性にデータが保存されていることがわかります。

まとめ

PHPアプリケーションのセッション管理に、DynamoDBを使ってみました。セッションハンドラが用意されていて、各フレームワークへの組み込みもハードル高くなさそうですね。ちなみにLaravelだと、Session Driverがサポートしているようで、より簡単に扱えそうです。近日中に試してみたいと思います。