サーバー連携
API パラメーターと公式 SDK の例を使い、サイトに端末登録と確認フローを組み込みます。
AuthLink の本番 API は https://api.getauthlink.com です。業務バックエンドには自サイトの API を指定し、AuthLink 公式サイトのドメインは API 呼び出しに使いません。
連携フローと信頼境界
- 運営者がサイト専用のテナントを作成し、認証情報をサイトのバックエンドへ渡します。
- バックエンドがログイン済みセッションから安定したユーザー ID を取得し、ランダムな state と作成用・消費用の冪等キーを生成します。
- bind / confirm リクエストを作成し、ユーザー、セッション、用途、state、requestId、expiresAt、冪等キーを保存します。その後、公開 ticket のみをブラウザーに返します。
- ユーザーが AuthLink でサイト、アカウント、数字を照合し、リクエストを承認します。
- approved / consumed を取得したら、保存済みの state と消費用キーで consume を呼び出します。
- 受領結果を検証し、自分のデータベースのトランザクションで requestId / verificationId を一意に保存してから confirmed を返します。保護対象の処理はこの記録を確認します。
webhook はありません。approved、6 桁の数字、フロントエンドのコールバックだけで処理を許可してはいけません。AuthLink は action、金額、transactionHash、権限範囲を受け取りません。
テナントと認証
運営者からサイト専用の tenantId、apiKey、origin、expiresAt を取得してください。新しい鍵に有効期限はありません。運営者は引き続き鍵の更新・失効やテナントの無効化ができます。既存の鍵は元の有効期限を維持します。鍵はサイトのバックエンドのみで安全に保存してください。
| ヘッダー | 要件 |
|---|---|
Authorization
|
Bearer <tenant API key>。すべての integration エンドポイントで必須です |
Content-Type
|
POST では application/jsonを使用し、未知のフィールドと重複 JSON キーを拒否します |
Idempotency-Key
|
作成と消費で必須です。英数字・アンダースコア・ハイフンの 16~128 文字。32 バイトの安全な乱数を Base64URL にする方法を推奨します。再試行時は同じキーを使います。 |
Origin / Cookie
|
API はブラウザーの Origin と Cookie を受け付けません。ブラウザーは自分のサイトのバックエンドを経由します。 |
リクエスト作成とパラメーター
POST /v1/integration/requests · API origin:
{
"externalUserId": "stable-user-id",
"accountLabel": "Account display name",
"purpose": "bind",
"state": "REPLACE_WITH_SAVED_43_CHARACTER_RANDOM_STATE"
}
| フィールド | 型 / 必須 | 説明 |
|---|---|---|
externalUserId
|
string / 必須 | 表示可能な ASCII(0x21~0x7e)の 1~128 バイト。ログイン済みセッションから取得し、再利用やブラウザーによる指定を許可しません。 |
accountLabel
|
string / 必須 | 空文字不可、UTF-8 で最大 160 バイト。制御文字と指定された双方向制御文字を拒否します。 |
purpose
|
string / 必須 | 初回登録は bind、登録後の確認は confirm
|
state
|
string / 必須 | 32 バイトの安全な乱数をパディングなし Base64URL にした 43 文字。バックエンドに保存し、消費時に元の値と照合します。 |
成功時は HTTP 200 と ticket を返します。
| レスポンスのフィールド | 意味 |
|---|---|
requestId
|
43 文字のリクエスト識別子 |
purpose / expiresAt
|
リクエストの用途と UTC ISO 形式の有効期限。有効期間は 120 秒です |
qr
|
QR の JSON 文字列:v、origin、requestId、token。フロントエンドのコンポーネントまたはアプリのみに渡し、ログには残しません。 |
qrSvg
|
互換用のフィールドです。公式 Web パッケージは QR を自ら生成し、この値を innerHTML で挿入しません |
pairingCode
|
現在の 6 桁の文字列。先頭のゼロを保持してください |
displayCode
|
value、serverTime、validUntil、periodSeconds:30 |
同じアカウントの新しいリクエストは、未完了の古いリクエストを拒否します。数字の更新で有効期限は延長されず、リクエストの再作成も不要です。
状態・消費・アカウント API
| メソッド / パス | 入力 | 戻り値 / 補足 |
|---|---|---|
GET /v1/integration/requests/{id}
|
テナント bearer | requestId、status、expiresAt、省略可能な displayCode。状態:new / pending / approved / consumed / rejected / expired |
POST /v1/integration/requests/{id}/consume
|
テナント bearer、Idempotency-Key、body は {"state":"saved-43-character-state"}
|
承認後に消費して confirmed を取得します。通信結果が不明なときは保存済みの消費用キーを再利用します。 |
POST /v1/integration/accounts/status
|
テナント bearer、body は {"externalUserId":"..."}
|
externalUserId、status:unbound/bound/deleted、platform(未登録の場合は null) |
POST /v1/integration/accounts/delete
|
テナント bearer、body は {"externalUserId":"..."}
|
{"status":"deleted"}。このサイトの AuthLink 紐付けを永久に失効させ、再登録できなくなります。CMS ユーザーは削除しません。 |
| 消費結果のフィールド | 検証内容 |
|---|---|
status / authenticationPolicy
|
status は confirmed であること。authenticationPolicy は公式 SDK が検証します |
requestId / tenantId / externalUserId
|
保存済みのリクエスト、テナント、ログインユーザー、セッションと一致すること |
purpose / state / expiresAt
|
バックエンドに保存した値と完全に一致し、有効期限内であること |
verificationId / platform / consumedAt
|
結果 ID、android / ios、日時を検証し、一意制約付きで保存すること |
Go SDK とメソッド
独立したモジュール authlink.local/sdk。Go 1.22 以降に対応し、標準ライブラリーのみを使用します。Go 製サイトのバックエンド向けで、AuthLink サーバーや MySQL ドライバーの導入は不要です。
Go SDK のソースをダウンロード · 完全なサンプルを読む →
インストールと初期化
展開後も SDK 自身の go.mod を保持し、サイトのプロジェクトには SDK モジュールのみを組み込んでください。
SDK はソースで配布しており、公開 Go モジュールは未リリースです。サイトの Go プロジェクトに展開し、ローカルの replace 指定を使ってください。
mkdir -p third_party
tar -xzf authlink-go.tar.gz -C third_party
go mod edit -replace=authlink.local/sdk=./third_party/authlink-go
go mod edit -require=authlink.local/[email protected]
go mod tidy
import authlink "authlink.local/sdk"
client, err := authlink.New(authlink.Config{
Origin: "https://api.getauthlink.com", // API origin, not the marketing site
TenantID: os.Getenv("AUTHLINK_TENANT_ID"),
APIKey: os.Getenv("AUTHLINK_API_KEY"),
})
if err != nil { return err }
// Get userID and label from your authenticated website session.
state, err := authlink.RandomToken()
if err != nil { return err }
createKey, err := authlink.RandomToken()
if err != nil { return err }
consumeKey, err := authlink.RandomToken()
if err != nil { return err }
// Persist state, both keys and user/session first. Reuse them on retries.
ticket, err := client.CreateRequest(ctx, authlink.CreateInput{
ExternalUserID: userID, AccountLabel: label,
Purpose: "bind", State: state,
}, createKey)
if err != nil { return err }
expected := authlink.Expected{
RequestID: ticket.RequestID, ExternalUserID: userID,
Purpose: ticket.Purpose, State: state, ExpiresAt: ticket.ExpiresAt,
}
// Save expected and consumeKey before returning the public ticket.
// Load saved expected / consumeKey after checking session, CSRF and ownership.
status, err := client.Status(ctx, expected.RequestID)
if err != nil { return err }
if status.Status == "approved" || status.Status == "consumed" {
result, err := client.Consume(ctx, expected, consumeKey)
if err != nil { return err }
// The SDK has validated the full receipt. Persist a unique confirmation
// in your own transaction, associated with this user/session and business.
_ = result
}
| Config の設定 | 説明 |
|---|---|
Origin / TenantID / APIKey | 必須:末尾にスラッシュのない API HTTPS origin、テナント ID、非公開のバックエンド用キー |
AllowLocalHTTP | 既定値は false。開発時のループバック / localhost のみ許可します |
HTTPClient | 省略可能な *http.Client。SDK はこれをコピーし、リダイレクトを拒否して CookieJar を無効化します。信頼できる transport を使用してください。各リクエストは最大 10 秒で、より短い context の期限や client timeout が優先されます。 |
| メソッド | 戻り値と用途 |
|---|---|
CreateRequest(ctx, CreateInput, key) | (Ticket, error)。CreateInput:ExternalUserID、AccountLabel、Purpose、State。既定の用途は confirm、初回登録は bind です。 |
Status(ctx, requestID) | (RequestStatus, error)。状態と現在の displayCode を取得します。これだけで処理を許可してはいけません。 |
Consume(ctx, Expected, key) | (Confirmation, error)。結果を消費し、ポリシー、テナント、ユーザー、リクエスト、用途、state、期限、結果 ID、プラットフォームを検証します。 |
WaitForConfirmation(ctx, Expected, key, interval) | (Confirmation, error)。任意のバックエンドポーリング。approved / consumed の結果を消費します。interval=0 の既定値は 1500 ミリ秒、指定範囲は 100 ミリ秒~10 秒です。 |
AccountStatus(ctx, externalUserID) | (AccountStatus, error)。unbound / bound / deleted を取得します。Platform は null を許容する *string です。 |
DeleteAccount(ctx, externalUserID) | error。このサイトの AuthLink 紐付けを永久に失効させ、再登録できなくなります。CMS ユーザーは削除しません。 |
RandomToken() | (string, error)。32 バイトの安全な乱数を Base64URL にします。state、作成キー、消費キーを別々に生成して保存してください。 |
ValidateConfirmation(result, expected, tenantID, now) | error。フィールドの検証のみで、署名検証ではありません。ブラウザーから送られた結果を認可の根拠にしないでください。 |
Expected には RequestID、ExternalUserID、Purpose、State、ExpiresAt が含まれます。バックエンドの保存済みリクエストから読み込み、expiresAt の元の文字列を保持してください。戻り値の構造体には公式 Web コンポーネント向けの JSON タグがあります。未知のフィールド、重複キー、大文字小文字の別名は拒否します。仕様のフィールド変更時は SDK も更新してください。
待機・キャンセル・エラー
result, err := client.WaitForConfirmation(ctx, expected, consumeKey, 0)
switch {
case err == nil:
// Persist result in your own transaction before updating UI or authorizing work.
_ = result
case errors.Is(err, authlink.ErrRejected):
// The user rejected the request.
case errors.Is(err, authlink.ErrExpired):
// The request expired.
case errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
// This call was canceled or timed out; the platform request is not revoked.
default:
var api *authlink.APIError
if errors.As(err, &api) {
// Handle api.StatusCode / api.Code; retry with the same consumption key.
}
}
Go の完全なサンプル
サンプルは create でリクエストを作成し、result で保存済みリクエストを照会・消費する二段階です。スマートフォンで承認してから result を実行してください。サイトのセッション管理やデータベース保存は含まれず、業務処理の認可を代行しません。
Go の完全なサンプルを開く・閉じる
// This example creates a request, then queries/consumes a previously saved one.
// Supply tenant credentials only through your backend's private environment.
package main
import (
"context"
"encoding/json"
"errors"
"flag"
"fmt"
"os"
"time"
authlink "authlink.local/sdk"
)
func run() error {
mode := flag.String("mode", "create", "create or result")
user := flag.String("user", "", "stable user ID from your authenticated session")
label := flag.String("label", "", "account display label")
purpose := flag.String("purpose", "bind", "bind or confirm")
flag.Parse()
client, err := authlink.New(authlink.Config{Origin: os.Getenv("AUTHLINK_ORIGIN"), TenantID: os.Getenv("AUTHLINK_TENANT_ID"), APIKey: os.Getenv("AUTHLINK_API_KEY")})
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
switch *mode {
case "create":
// For this standalone example, supply already-generated and saved values
// through the environment. A website must persist them before networking.
ticket, err := client.CreateRequest(ctx, authlink.CreateInput{ExternalUserID: *user, AccountLabel: *label, Purpose: *purpose, State: os.Getenv("AUTHLINK_STATE")}, os.Getenv("AUTHLINK_CREATE_KEY"))
if err != nil {
return err
}
// Contains QR token: deliver to the intended user's UI; never log it.
return json.NewEncoder(os.Stdout).Encode(ticket)
case "result":
expected := authlink.Expected{RequestID: os.Getenv("AUTHLINK_REQUEST_ID"), ExternalUserID: *user, Purpose: *purpose, State: os.Getenv("AUTHLINK_STATE"), ExpiresAt: os.Getenv("AUTHLINK_EXPIRES_AT")}
status, err := client.Status(ctx, expected.RequestID)
if err != nil {
return err
}
if status.Status != "approved" && status.Status != "consumed" {
return json.NewEncoder(os.Stdout).Encode(status)
}
result, err := client.Consume(ctx, expected, os.Getenv("AUTHLINK_CONSUME_KEY"))
if err != nil {
return err
}
// In a website, persist result atomically with unique request/result IDs,
// user/session and business association before returning confirmed.
_ = result
fmt.Fprintln(os.Stderr, "Receipt validated; this example does not persist or authorize business.")
return nil
default:
return errors.New("mode must be create or result")
}
}
func main() {
if err := run(); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
}
実行オプション
| パラメーター | 用途 |
|---|---|
-mode | create はリクエスト作成、result は照会と消費を行います。既定値は create です。 |
-user | バックエンドのセッションから取得した、ログイン済みユーザーの固定 ID。 |
-label | リクエスト作成時に表示するアカウント名。 |
-purpose | 初回登録は bind、以降の確認は confirm を使います。このサンプルの既定値は bind です。 |
バックエンドの環境変数
| 変数 | 用途 |
|---|---|
AUTHLINK_ORIGIN / AUTHLINK_TENANT_ID / AUTHLINK_API_KEY | 運営者から提供される API アドレス、テナント ID、秘密キー。サイトのバックエンドでのみ保管してください。 |
AUTHLINK_STATE / AUTHLINK_CREATE_KEY / AUTHLINK_CONSUME_KEY | バックエンドで state、作成用キー、消費用キーを個別に生成・保存し、再試行時にも同じ値を使います。 |
AUTHLINK_REQUEST_ID / AUTHLINK_EXPIRES_AT | result ではバックエンドに保存した ticket からリクエスト ID と元の有効期限を読み込みます。 |
同じサンプルは SDK 一式の examples/quickstart/main.go に含まれています。上のコードを main.go にコピーすることもできます。認証情報はバックエンドの環境から設定し、ソースコードやブラウザーに書き込まないでください。
# Run from a Go project that already includes the SDK module.
# Supply the private environment variables listed above before running.
export AUTHLINK_ORIGIN=https://api.getauthlink.com
go run . -mode create -user stable-user-id -label "Example account" -purpose bind
# After phone approval, load the SAME saved request context before running:
go run . -mode result -user stable-user-id -purpose bind
Node SDK とメソッド
// Copy /sdk/node/ and /sdk/browser/ with their relative paths. Server import only.
import { AuthLink, randomToken } from './sdk/node/authlink.mjs';
const auth = new AuthLink({
origin: 'https://api.getauthlink.com',
tenantId: process.env.AUTHLINK_TENANT_ID,
apiKey: process.env.AUTHLINK_API_KEY,
});
// user must come from your authenticated session. This is the creation stage.
const state = randomToken();
const createKey = randomToken();
const consumeKey = randomToken();
// Persist these values and user/session before networking. Reuse on retries.
const ticket = await auth.createRequest({
externalUserId: user.id, accountLabel: user.displayName,
purpose: 'bind', state,
}, createKey);
const expected = { requestId: ticket.requestId, expiresAt: ticket.expiresAt,
externalUserId: user.id, purpose: 'bind', state };
// Save expected, consumeKey and session association before returning ticket.
// Your result endpoint loads the saved request context:
const status = await auth.status(expected.requestId);
if (['approved', 'consumed'].includes(status.status)) {
const verified = await auth.consume(expected, consumeKey);
// The SDK has verified the receipt. Persist a unique confirmation atomically.
// Return verified to the browser only after the database commit succeeds.
}
| 初期化オプション / メソッド | 説明 |
|---|---|
origin / tenantId / apiKey
|
必須:末尾にスラッシュのない API HTTPS origin、テナント ID、非公開キー |
allowLocalHttp
|
既定値は false。ループバックでの開発専用です |
createRequest(input, key)
|
リクエストを作成します。フィールドは上表を参照してください。purpose の既定値は confirm です。 |
status(requestId, signal?)
|
状態を取得します。signal は省略可能な AbortSignal です |
consume(expected, key, signal?)
|
結果を消費・検証し、検証済みの結果を返します |
waitForConfirmation(expected, options)
|
バックエンドのポーリング補助です。options.idempotencyKey と onConfirmed は必須。onRejected / onExpired、signal、intervalMs は省略可能です(既定値 1500、範囲 100~10000 ミリ秒)。結果の保存はアプリ側で行ってください。 |
accountStatus(id) / deleteAccount(id)
|
このテナントのアカウント紐付けを照会 / 永久失効 |
インストール方法、メソッドの設定項目、使用例はこのページにあります。Node SDK と必要な依存ファイルは一つの圧縮ファイルにまとめました。展開後も node と browser の相対パスを保持し、Web コンポーネントは npm でインストールしてください。
mkdir -p sdk
tar -xzf authlink-node.tar.gz -C sdk
# Import ./sdk/node/authlink.mjs from your backend project.
エラー処理
| HTTP | 主な code | 対応 |
|---|---|---|
| 400 | INVALID_REQUEST / INVALID_SUBJECT / INVALID_DISPLAY_TEXT / INVALID_IDEMPOTENCY_KEY | 入力の制約を確認してください。結果が不明な状態を解消するために新規リクエストを繰り返し作成しないでください。 |
| 401 | UNAUTHORIZED / STATE_MISMATCH / SERVER_CREDENTIAL_REQUIRED | 非公開の認証情報、state、Host、サイトのバックエンドを経由しているかを確認してください。 |
| 404 | NOT_FOUND | リクエストまたは配布チャネルが存在しません |
| 409 | APPROVAL_REQUIRED / REQUEST_EXPIRED / REQUEST_USED / IDEMPOTENCY_CONFLICT / ACCOUNT_ALREADY_BOUND / ACCOUNT_NOT_BOUND | 状態に応じて処理してください。期限切れ後の再作成はユーザー操作で行い、冪等な復旧を維持してください。 |
| 429 | RATE_LIMITED / BUSY | 時間を空け、元の冪等キーで再試行してください |
| 503 | ATTESTATION_UNAVAILABLE | 確認サービスを一時的に利用できません。時間をおいて再試行してください。 |
エラーの body: {"code":"..."}。未知のエラーを成功として扱わないでください。API レスポンスの共有キャッシュは禁止です。bearer キー、QR token、証明全体、秘密情報をログに残さないでください。