ローコードプラットフォームSPIRALのAPIを利用する（会員管理機能の使い方）

[SPIRAL](https://www.spiral-platform.co.jp/)は、主にエンタープライズ向けのローコードプラットフォームになります。ローコードプラットフォームなので、プログラミング知識がなくともWebアプリケーションを開発できるのが魅力です。

SPIRALでは、自社のシステムや外部システムと連携する場合を想定して、APIが公開されています。今回は、そのAPIを利用して、認証などの会員管理機能の使い方を紹介します。

## 注意点

SPIRALでは、SPIRAL内部で動作するアカウント内APIと、外部APIの2種類があります。アカウント内APIでは、簡単に操作できるPHP SDKがありますが、外部公開はされていません。そのため、今回はPHPの `file_get_contents` などを使ってAPI操作をしています。

## 準備

### APIトークンの取得

SPIRALの管理画面で、APIトークンを作成します。ダッシュボードの開発メニュー内のAPIトークンにて、新しいAPIトークンを作成します。

作成後に入手できるAPIトークンと、APIトークンシークレットをメモしておきます。


![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/03a9140a-16fb-4d3d-b28f-8d5e539293ae.png)


### データベースの作成

今回作成したのは通常DBになります。SPIRALでは、この他8種類のデータベースが利用できます。

[【機能紹介】各種DB \| SPIRAL ナレッジサイト](https://knowledge.spirers.jp/article/design/detail/730)

データベースの名前は `mailmagazine_db` としました。作成したフィールドは[メール会員管理（ID/パスワード管理） SPIRAL ver\.1 サポートサイト](https://support.smp.ne.jp/tips/tips22/)に記載の通りです。フィールドは以下の通りです。

| フィールド名           | サンプル値                 | 型                                 | 差し替えキーワード |
| ---------------------- | -------------------------- | ---------------------------------- | ------------------ |
| お名前                 | テキスト30文字前後         | テキストフィールド(64 bytes)       | name               |
| メールアドレス         | aaa@bbb.cc.dd              | メールアドレス（大・小文字を無視） | mail               |
| パスワード             | 半角英数字10桁前後         | メッセージダイジェスト(SHA256)     | password           |
| 都道府県               | プルダウンから選択         | 都道府県                           | pref               |
| 性別                   | 男性、女性                 | 性別                               | gender             |
| 血液型                 | A型、B型、O型、AB型、不明  | セレクト                           | bloodType          |
| 登録日時               | yyyy年mm月dd日hh時mm分ss秒 | 登録日時                           | registDate         |
| 更新日時               | yyyy年mm月dd日hh時mm分ss秒 | 日付（○年○月○日 ○時○分○秒）        | lastUpdate         |
| 不正アドレスフラグ     | 不正アドレスフラグ         | 不正アドレスフラグ                 | invalidEmail       |
| モバイルドメインフラグ | モバイルドメイン           | モバイルドメインフラグ             | mobileFlg          |
| 重複フラグ             | 重複フラグ                 | 重複フラグ                         | duplicateFlg       |
| 配信エラーカウント     | 配信エラーカウント         | 配信エラーカウント                 | errorCount         |
| オプトアウト           | オプトアウト               | オプトアウト                       | stop               |
| 変更・停止キー         | 英数ランダム16桁           | 簡易パスワード                     | authKey            |
| ユーザーエージェント   | ユーザーエージェント       | テキストフィールド(128 bytes)      | userAgent          |

### マイエリアの作成

管理画面の `Web` にある `マイエリア` から、新しいマイエリアを作成します。会員専用のページの集まりのことです。マイエリア機能を用いることで、ノーコードで会員専用ページや会員専用アンケート、会員情報変更ページ等を構築できます。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/fb0fdb7f-cbfc-48b7-8197-7214ed218b2c.png)



認証を行う際には、このマイエリアが必要になりますので、新しく作成します。今回は `my_area` という名前で作成しました。

## コードについて

今回はPHPで作成しています。

### APIトークンの保存

APIトークンとシークレットは、環境変数に保存します。以下のように `.env` ファイルを作成し、トークンを保存します。

```env
API_TOKEN=your_api_token
API_TOKEN_SECRET=your_api_token_secret
```

.env の読み込みは `vlucas/phpdotenv` を使っています。インストールは `composer` で行います。

```bash
composer require vlucas/phpdotenv
```

次に、PHPのコード内で `.env` を読み込みます。

```php
require_once __DIR__ . "/vendor/autoload.php";

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();
```

### APIリクエストURLの取得

APIでリクエストするURLは、以下の手順で取得します。


```php
// ロケータのURL (変更の必要はありません)
$locator = "https://www.pi-pe.co.jp/api/locator";

// スパイラルの操作画面で発行したトークンを設定します。
$TOKEN = $_ENV['API_TOKEN'];
$SECRET = $_ENV['API_TOKEN_SECRET'];

// API用のHTTPヘッダ
$api_headers = array(
    "X-SPIRAL-API: locator/apiserver/request",
    "Content-Type: application/json; charset=UTF-8",
);

// 送信するJSONデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン

// 送信用のJSONデータを作成します。
$json = json_encode($parameters);

// curlライブラリを使って送信します。
$curl = curl_init($locator);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
curl_setopt($curl, CURLOPT_HTTPHEADER, $api_headers);
curl_exec($curl);

// エラーがあればエラー内容を表示
if (curl_errno($curl)) echo curl_error($curl);
$response = curl_multi_getcontent($curl);
curl_close($curl);
$response_json = json_decode($response, true);

// サービス用のURL
$APIURL = $response_json['location'];
```

この時のレスポンスは以下のようになっています。詳細は[SPIRAL ver\.1 API リファレンス](https://support.smp.ne.jp/api/index.html#operation/locatorApiserver)にて確認してください。

```json
{
  "code": 0,
  "message": "OK",
  "location": "https://（APIサーバ）/api/service",
  "default_version": 2,
  "supported_version": [1, 2],
  "use_client_crt": "f"
}
```

`location` にAPIサーバのURLが入っています。

## 新規登録

新規登録する際には、 `data` パラメータに対して必要な情報を設定します。

```php
// API用のHTTPヘッダ
$api_headers = array(
  "X-SPIRAL-API: database/insert/request",
  "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン
$parameters["db_title"] = "mailmagazine_db"; //DBのタイトル
$parameters["passkey"] = time(); //エポック秒

// 登録したいデータを設定します（１件分）
$parameters["data"] = array(
    array("name" => "registDate", "value" => "now"),
    array("name" => "mail", "value" => "user@example.com"),
    array("name" => "name", "value" => "Your Name"),
    array("name" => "password", "value" => 'your_password'),
);

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, $SECRET, false);

// JSON形式にエンコードします
$json = json_encode($parameters);

// curlライブラリを使って送信します。
$curl = curl_init($APIURL);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
curl_setopt($curl, CURLOPT_HTTPHEADER, $api_headers);
curl_exec($curl);

// エラーがあればエラー内容を表示
if (curl_errno($curl)) echo curl_error($curl);
$response = curl_multi_getcontent($curl);
curl_close($curl);

// 画面に表示
// 配列にしたい時は json_decode($response, true); とします。
print_r(json_decode($response, true));
?>
```

レスポンスは以下のようになります。

```json
{
  "code": "0",
  "id": "4",
  "message": "OK"
}
```

## ログイン

ログイン処理です。この時には、前述のマイエリアの名前が必要です。

```php
// ログインリクエスト
$api_headers = array(
    "X-SPIRAL-API: area/login/request",
    "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン
$parameters["passkey"] = time(); //エポック秒
$parameters["my_area_title"] = "my_area";
$parameters["id"] = $_ENV['ID'];
$parameters["password"] = $_ENV['PASSWORD'];
$parameters["url_type"] = "2";

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, $SECRET, false);

// JSON形式にエンコードします。
$json = json_encode($parameters);

// POSTで送信します。
$stream = stream_context_create(
    array('http' => array(
        'method' => 'POST',
        'protocol_version' => '1.0',
        'header' => $api_headers,
        'content' => $json
    ))
);

// レスポンスデータ読み込み
$response = file_get_contents($APIURL, false, $stream);
$response_json = json_decode($response, true);
print_r($response_json);

// セッションID
$jsessionid = $response_json['jsessionid'];
```

セッションIDは認証状態を維持する際に必要です。ログイン時のレスポンスは以下のようなJSONです。

```json
{
  "code": 0,
  "message": "OK",
  "jsessionid": "0323029CFD30EFA31C00912FC11F6D6B",
  "session_expire": 1603250145,
  "url": "https://www.example.com/area/servlet/area.MyPageBundle?MyPageID=f54...7l1",
  "auto_login_cookie": "r10...ded",
  "auto_login_limit": 1603334087
}
```

### 認証状態の確認

セッションIDの有効性チェックを行う処理です。 `jsessionid` を指定して、リクエストを行います。

```php
// ログイン確認リクエスト
$api_headers = array(
    "X-SPIRAL-API: area/status/request",
    "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン
$parameters["passkey"] = time(); //エポック秒
$parameters["my_area_title"] = "my_area";

// セッションIDを付けます
$parameters["jsessionid"] = $jsessionid;

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, $SECRET, false);

// JSON形式にエンコードします。
$json = json_encode($parameters);

// POSTで送信します。
$stream = stream_context_create(
    array('http' => array(
        'method' => 'POST',
        'protocol_version' => '1.0',
        'header' => $api_headers,
        'content' => $json
    ))
);

// レスポンスデータ読み込み
$response = file_get_contents($APIURL, false, $stream);
$response_json = json_decode($response, true);

// 画面に表示
print_r($response_json);
```

この時のレスポンスは以下のようなJSONです。

```json
{
  "code": 0,
  "message": "OK",
  "jsessionid": "0323029CFD30EFA31C00912FC11F6D6B",
  "session_expire": 1603250145,
  "auto_login_cookie": "r10...ded",
  "auto_login_limit": 1603334087,
  "status": 1
}
```

### ログアウト

ログアウト処理です。

```php
// ログアウトリクエスト
$api_headers = array(
    "X-SPIRAL-API: area/logout/request",
    "Content-Type: application/json; charset=UTF-8",
);

// リクエストデータを作成
$parameters = array();
$parameters["spiral_api_token"] = $TOKEN; //トークン
$parameters["passkey"] = time(); //エポック秒
$parameters["my_area_title"] = "my_area";

// セッションIDを付けます
$parameters["jsessionid"] = $jsessionid;

// 署名を付けます
$key = $parameters["spiral_api_token"] . "&" . $parameters["passkey"];
$parameters["signature"] = hash_hmac('sha1', $key, $SECRET, false);

// JSON形式にエンコードします。
$json = json_encode($parameters);

// POSTで送信します。
$stream = stream_context_create(
    array('http' => array(
        'method' => 'POST',
        'protocol_version' => '1.0',
        'header' => $api_headers,
        'content' => $json
    ))
);

// レスポンスデータ読み込み
$response = file_get_contents($APIURL, false, $stream);
print_r($response);
```

レスポンスのJSONは、以下のようになります。

```json
{
  "code": 0,
  "message": "OK",
  "url": "https://www.example.com/area/servlet/are...7l1",
  "jsessionid": "032...D6B",
  "auto_login_cookie": "r109...ded",
  "auto_login_limit": 1603334087
}
```

## まとめ

今回はSPIRALのAPIを利用して、会員管理機能（新規登録・ログイン・ログアウト）を利用する流れを紹介しました。SPIRALを使って、社内システムや外部システムと連携する際の参考にしてください。

なお、1分あたりのAPIのリクエスト数は、契約によって上限があります。ご注意ください（詳細は[APIのリクエスト数制限を知りたい SPIRAL ver\.1 サポートサイト](https://support.smp.ne.jp/faq/api-faq/f0094/)にて）。

[API SPIRAL ver\.1 サポートサイト](https://support.smp.ne.jp/api-manuals/)