Multipassを使用したログインは、別々のウェブサイトとSHOPLINEストアを持つストアオーナー向けに設計されています。これは、顧客をウェブサイトからSHOPLINEストアにリダイレクトし、元のサイトで使用するのと同じメールアドレスでシームレスにログインさせるものであり、バインドされていないか作成されていない場合は新しいアカウントも作成します。顧客データベースを同期する必要がないため、このアプリはユーザーに大きな利便性をもたらすことができます。
この記事では、Multipassとは何か、どのように使用されるか、およびそのセキュリティ機能について説明します。
目次
- Multipassの使用方法
- 実装ケース
- セキュリティ上の懸念
- よくある質問
Multipassの使用方法
SHOPLINEでMultipassを有効にする
-
SHOPLINEの管理パネルから、設定 > 顧客アカウント > 顧客アカウントタイプに移動します。 クラシック顧客アカウントを選択していることを確認します。 クラシック顧客アカウントセクションに移動し、Multipassでログイン > 編集をクリックして有効にするをクリックします。
- 有効になると、「暗号化キー」が送信されます。このキーは、顧客がストアにログインするためのトークンを生成する際に必要です。キーを安全な場所に保管してください。
顧客情報をJSON形式にエンコードする
顧客情報はハッシュ値として表され、少なくとも顧客のメールアドレスと現在のタイムスタンプ(ISO8601を参照)を含む必要があります。顧客の名前、姓、複数の発送住所、または顧客の現在のブラウザセッションのIPアドレスを含めることもできます。
すべての必須フィールドを含むサンプルハッシュ値:
{
“email”: “peter@shopline.com”,
“created_at”: “2013-04-11T15:16:23-04:00”,
}
オプションフィールドを含むサンプルハッシュ値:
{
“email”: “peter@shopline.com”,
“created_at”: “2013-04-11T15:16:23-04:00”,
“first_name”: “Peter”,
“last_name”: “jason”,
“tag_string”: “canadian, premium”,
“identifier”: “peter123”,
“remote_ip”: “107.20.160.121”,
“return_to”: “http://yourstore.com/some_specific_site”,
“addresses”: [
{
“address1”: “123 Oak St”,
“city”: “Ottawa”,
“country”: “Canada”,
“first_name”: “Peter”,
“last_name”: “Jason”,
“phone”: “555-1212”,
“province”: “Ontario”,
“zip”: “123 ABC”,
“province_code”: “ON”,
“country_code”: “CA”,
“default”: true
}
]
}
顧客にタグを付与する場合は、「tag_string」をコンマで区切られた一語の値のリストに設定します。これらのタグは、この顧客に関連付けられている可能性のあるタグを上書きします。
顧客にストアの特定のページを表示させたい場合は、return_toフィールドを使用します。
注意事項: SHOPLINEでは、ユーザーの一意の識別子としてメールアドレスを使用します。SHOPLINEで顧客を登録する際は、次の場合に識別子フィールドに一意の識別子を設定する必要があります:
メールアドレスが常に一意である場合、識別子フィールドは必要ありません。特定のメールアドレスは、1つのSHOPLINEアカウントのみを登録するために使用できます。別のアカウントを登録する場合(異なる「識別子」であっても)、エラーが発生します。 |
JSONデータのAES暗号化
有効なマルチパスログイントークンを生成するには、SHOPLINE管理者から提供されたキーが必要です。このキーは、暗号化用と署名用の2つの暗号鍵を導出するために使用されます。このキー導出はSHA-256ハッシュ関数を使用して行われます(最初の128ビットが暗号化キーとして使用され、最後の128ビットが署名キーとして使用されます)。
暗号化は機密性を提供し、誰も顧客データを読むことができないようにします。暗号化キー(128ビット、CBCモード、およびランダム初期化ベクトル)はAESアルゴリズムを使用して生成されます。
HMACを使用した暗号化データの署名
署名(メッセージ認証コードとも呼ばれる)は信頼性を提供します。暗号化されたJSONデータ(平文のJSONデータの代わりに)は、SHA-256のHMACアルゴリズムを使用して署名されます。
Base64を使用したバイナリデータのエンコード
マルチパスログイン用のトークンは、128ビットの初期化ベクトル、可変長の暗号文、および256ビットの署名(ここで述べられている順序で)で構成されています。これはBase64を使用してエンコードされます(RFC 4648で指定されているURLセーフアルファベットを使用)。
ユーザーをSHOPLINEストアにリダイレクトする
トークンを取得したら、HTTP GETリクエストはSHOPLINEストアにリダイレクトされます。
HTTP GETリクエスト: api/user/account/login/multipass/insert_token_here
リクエストが成功した場合(たとえば、トークンが有効で期限切れでない場合)、ユーザーはSHOPLINEストアにログインします。
トークンは短期間のみ有効で、1度しか使用できないため、事前にトークンを生成しないでください。それ以外の場合、リクエストはHTMLウェブサイトにリダイレクトされます。必要なときにリダイレクトURLを作成し、トークンを生成してブラウザ経由で自動的にストアにリダイレクトできるようにしてください。
実装ケース
以下はJavaでトークンを生成する基本的なケースを示しています:
public static void main(final String[] args) throws Exception {
final String createAt = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT);
final Map<String, String> dataMap = new HashMap<>();
dataMap.put("メール", "peter@shoplineapp.com");
dataMap.put("created_at", createAt);
final String dataJson = "..."; //dataMapからのjson文字列
final String secret = "...";
final String token = generateToken(secret, dataJson);
log.info("plaintext={}, token={}", dataJson, token);
}public static String generateToken(final String secret, final String plaintext) throws Exception {
// SHA-256ハッシュ
final MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
final byte[] encodedHash = messageDigest.digest(secret.getBytes(StandardCharsets.UTF_8));
final byte[] encryptedKey = new byte[16];
final byte[] signKey = new byte[16];
System.arraycopy(encodedHash, 0, encryptedKey, 0, 16);
System.arraycopy(encodedHash, 16, signKey, 0, 16);
// iv
final byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
final SecretKeySpec encryptedKeySpec = new SecretKeySpec(encryptedKey, "AES");
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, encryptedKeySpec, new IvParameterSpec(iv));
// バイト配列を暗号化
final byte[] encrypted = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
final byte[] ivEncryptedByte = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, ivEncryptedByte, 0, iv.length);
System.arraycopy(encrypted, 0, ivEncryptedByte, iv.length, encrypted.length);
final Mac hmac = Mac.getInstance("HmacSHA256");
final SecretKeySpec signKeySpec = new SecretKeySpec(signKey, "HmacSHA256");
hmac.init(signKeySpec);
// バイト配列に署名、256ビット
final byte[] signByte = hmac.doFinal(ivEncryptedByte);
final byte[] tokenBytes = new byte[ivEncryptedByte.length + signByte.length];
System.arraycopy(ivEncryptedByte, 0, tokenBytes, 0, ivEncryptedByte.length);
System.arraycopy(signByte, 0, tokenBytes, ivEncryptedByte.length, signByte.length);
String token = Base64.encodeBase64URLSafeString(tokenBytes);
token = token.replace('+', '-').replace('/', '_');
return token;
}
セキュリティ上の懸念事項
SHOPLINEは、指定されたブラウザのみがトークンを使用できるように、常にカスタマーデータハッシュ値のremote_ipフィールドを設定するようお勧めします。SHOPLINEはまた、トークンをブラウザに送信する際に安全なHTTPS接続を使用することをお勧めします。
メインウェブサイトで新しいアカウントを登録する際に、使用されるメールアドレスの検証が必要であることを確認してください。そうでない場合、アカウントのセキュリティが危険にさらされる可能性があります。
よくある質問
- Q1: 大規模なユーザーデータベースを持っています。SHOPLINEと同期して、Multipassでログインできるようにするにはどうすればよいですか?
A1: 何も同期する必要はありません。Multipassでログインすると、顧客のリクエストをリダイレクトするためにアカウントが自動的に作成されます(以前にアカウントが作成されていない場合)。 - Q2: 一部の顧客がすでにSHOPLINEで注文をしています。これらの顧客の情報を更新して、Multipassでログインできるようにするにはどうすればよいですか?
A2: 顧客APIを使用して、顧客APIを使用して、顧客のmultipass_identifierを設定できます。 これらの顧客アカウントのすべてのログインには、この識別子が必要です。 - Q3: キーが漏洩しました。どうすればよいですか?
A3: キーが漏洩した場合は、ストアの管理ページで無効にできます。再度有効にすると新しいキーが生成されます。これにより、すべての元のURLが無効になります。キーをすぐに無効にすべきです。なぜなら、キーを知っているすべての人が、顧客アカウントを使用してストアにアクセスする可能性があるからです。 - Q4: SHOPLINEストア間でMultipassでログインできますか?
A4: いいえ、Multipassは外部ウェブサイトにリダイレクトせずに、複数のSHOPLINEストア間でログインすることはできません。 - Q5: Multipassでログインは卸売チャネルに適用されますか?
A5: いいえ、Multipassでログインは卸売チャネルには使用できません。 - Q6: remote_ipフィールドはIPv6アドレスをサポートしていますか?
A6: いいえ、IPv4アドレスのみがサポートされています。remote_ipの値が顧客データハッシュ値で指定されたIPアドレスと一致しない場合、Multipassでのログインはエラーを返します。「Multipassでログインする権限がありません」と表示されます。
コメント