メインコンテンツまでスキップ

認証の追加

Squid はさまざまな認証プロバイダーと統合できます。これらを Squid に接続することで、ユーザーの操作を認可し、プロジェクトのセキュリティを強化できます。

認証を使う理由

ほとんどのアプリケーションでは、ユーザーが誰であるかを把握し、各ユーザーが何をできるかを制御する必要があります。Squid は既存の認証プロバイダーに接続するため、認証システムをゼロから構築することなく、ユーザーの本人確認とアクセス制御の強制を行えます。

概要

Squid はトークンを発行しません。代わりに、認証プロバイダーがトークンを発行し、クライアントがそれを Squid に渡し、Squid が検証して、認証の詳細をバックエンドコード内で利用できるようにします。

Squid は 2 つの認証方法をサポートします。

  • Bearer tokens(ユーザー認証): 認証プロバイダーがユーザーごとに JWT を発行します。クライアントはすべての Squid リクエストにこのトークンを付けて送信します。Squid はトークンを検証し、ユーザー詳細(user ID、有効期限、カスタム属性)を抽出します。どのユーザーがリクエストしているかを知る必要がある機能に使用します。
  • API keys(サーバー間認証): ユーザー識別情報なしでアクセスを許可する共有キーです。バックエンド間通信、管理用スクリプト、ユーザー識別が不要な自動処理に使用します。

対応プロバイダー

Squid は以下の認証プロバイダーをサポートします。

ProviderDescriptionDocs
Auth0OpenID Connect providerAuth0 のセットアップ
AWS CognitoAWS user pool serviceCognito のセットアップ
OktaEnterprise identity platformOkta のセットアップ
KeycloakOpen-source identity managementKeycloak のセットアップ
Firebase AuthGoogle Firebase authFirebase のセットアップ
DescopeNo-code CIAM platformDescope のセットアップ
JWT RSACustom RSA-signed JWTsJWT RSA のセットアップ

上記プロバイダーの多くは OpenID Connect(OIDC)プロトコルを使用します。これは OAuth 2.0 の上に構築された ID レイヤーで、アプリケーションがユーザー本人確認を行い、プロフィール情報を取得する方法を標準化します。OIDC を理解すると、プロバイダーを正しく設定し、トークンの問題をトラブルシュートしやすくなります。詳細はこちらを参照してください。

クイックスタート

前提条件

  • Squid アプリケーション(backend と client)
  • 上記の対応認証プロバイダーのいずれかのアカウント

Step 1: Squid Console で auth connector を追加する

Squid Console でアプリケーションに移動し、アプリケーション概要で Add auth provider をクリックします。希望する connector を選択し、必要な設定フィールドを入力します。

Step 1

プロバイダー固有の設定詳細は、上記の Supported providers 表にリンクされている各プロバイダーページを参照してください。

Step 2: クライアントを設定する

Console で connector をセットアップしたら、すべてのリクエストに auth token を付与して送信するように Squid client を設定します。

Client code
import { Squid, SquidAuthProvider } from '@squidcloud/client';

const squid = new Squid({ ... });

const authProvider: SquidAuthProvider = {
// Must match the connector ID you set in the Squid Console
integrationId: 'your_auth_connector_id',
getToken: () => {
// Return the token from your auth provider (e.g., Auth0, Firebase, Cognito)
return yourAuthLibrary.getAccessToken();
},
};

squid.setAuthProvider(authProvider);

Step 3: backend で auth を使う

auth provider を設定すると、backend へのすべてのリクエストに検証済みトークンが含まれます。任意の backend service メソッドで、認証済みユーザーの詳細にアクセスできます。

Backend code
import { executable, SquidService } from '@squidcloud/backend';

class MyService extends SquidService {
@executable()
getProfile(): { userId: string } | null {
const userAuth = this.getUserAuth();
if (!userAuth) {
return null;
}
return { userId: userAuth.userId };
}
}

クライアント側の設定

SquidAuthProvider インターフェース

SquidAuthProvider インターフェースは、Squid がクライアントから auth token を取得する方法を定義します。

interface SquidAuthProvider {
/** Must match the connector ID configured in the Squid Console. */
integrationId: string;

/**
* Returns a valid access token, or undefined if there is no active session.
* Called by Squid every time the client makes a request to the backend.
* Can be synchronous or asynchronous.
*/
getToken(): Promise<string | undefined> | string | undefined;
}
  • integrationId - Squid Console で設定した integration ID と完全に一致している必要があります。
  • getToken() - すべてのリクエストで呼び出されます。stringundefined、またはそれらのいずれかに解決される Promise を返せます。関数が undefined を返す場合、リクエストには認可情報が送信されません。

auth provider は Squid の constructor options で設定するか、setAuthProvider を呼び出して設定できます。

Client code
// Option 1: Set in the constructor
const squid = new Squid({
appId: 'your_app_id',
region: 'us-east-1',
authProvider: {
integrationId: 'auth0',
getToken: () => getAccessToken(),
},
});

// Option 2: Set after initialization
squid.setAuthProvider({
integrationId: 'auth0',
getToken: () => getAccessToken(),
});

トークンのキャッシュ

Squid はリクエストのたびに getToken() を呼び出すため、トークンをキャッシュし、有効期限が近づいたときのみ更新してください。

Client code
let cachedToken: string | undefined;
let tokenExpiry = 0;

const authProvider: SquidAuthProvider = {
integrationId: 'auth0',
getToken: async () => {
const now = Date.now();
// Renew the token 60 seconds before it expires
if (!cachedToken || now >= tokenExpiry - 60_000) {
const result = await yourAuthLibrary.getAccessToken();
cachedToken = result.token;
tokenExpiry = result.expiresAt;
}
return cachedToken;
},
};

API key 認証

API key 認証は、バックエンド間通信、管理操作、またはユーザー識別が不要な自動スクリプトに使用します。

Squid の constructor options で API key を渡します。

Client code
import { Squid } from '@squidcloud/client';

const squid = new Squid({
appId: 'your_app_id',
region: 'us-east-1',
apiKey: 'your_api_key',
});

API key 認証では userId は提供されません。個々のユーザーを識別する必要がない場合にのみ使用してください。

Squid API key は、Squid ConsoleApplication タブから確認または再作成できます。

backend で auth を使う

Auth ヘルパーメソッド

SquidService は、backend コードで認証を扱うために次のメソッドを提供します。

MethodReturnsDescription
isAuthenticated()booleanリクエストに有効な auth(ユーザートークンまたは API key)がある場合は true を返す
assertIsAuthenticated()voidリクエストが認証されていない場合に UNAUTHORIZED をスローする
getUserAuth()AuthWithBearer | undefinedリクエストが Bearer token を使用している場合にユーザー認証情報を返す
getApiKeyAuth()AuthWithApiKey | undefinedリクエストが API key を使用している場合に API key の詳細を返す

Auth type の形(shape)

リクエストが Bearer token(ユーザー認証)を使用する場合、getUserAuth()AuthWithBearer オブジェクトを返します。

interface AuthWithBearer {
type: 'Bearer';
/** The unique identifier of the authenticated user. */
userId: string;
/** The expiration timestamp of the token, in seconds. */
expiration: number;
/** Additional attributes associated with the token. */
attributes: Record<string, any>;
/** The raw JWT token string, if available. */
jwt?: string;
}

リクエストが API key を使用する場合、getApiKeyAuth()AuthWithApiKey オブジェクトを返します。

interface AuthWithApiKey {
type: 'ApiKey';
/** The API key string used for authentication. */
apiKey: string;
}

リクエストコンテキスト

すべての backend メソッドは this.context にアクセスでき、これは現在のリクエストに関する情報を持つ RunContext オブジェクトを返します。

interface RunContext {
/** Your application ID. */
appId: string;
/**
* The ID of the client that initiated this request. Only available for
* client-initiated requests (not triggers, schedulers, or webhooks).
*/
clientId?: string;
/** The IP address of the client that initiated this request. */
sourceIp?: string;
/** The headers of the request. Header keys are lowercase. */
headers?: Record<string, any>;
}

例: 認証が必要な backend メソッド

Backend code
import { executable, SquidService } from '@squidcloud/backend';

class UserService extends SquidService {
@executable()
getUserDashboard(): { userId: string; attributes: Record<string, any> } {
// Throws UNAUTHORIZED if no valid auth is present
this.assertIsAuthenticated();

const userAuth = this.getUserAuth();
if (!userAuth) {
throw new Error('This endpoint requires user authentication, not an API key');
}

return {
userId: userAuth.userId,
attributes: userAuth.attributes,
};
}
}

auth を security rules に接続する

認証データは Squid のセキュリティデコレーター(@secureDatabase@secureCollection など)に直接渡されます。security rules は、上で説明したのと同じ auth メソッドを使用して、データや API へのアクセスを制御します。

たとえば、コレクションに対するすべての操作で認証を必須にできます。

Backend code
import { secureCollection, SquidService } from '@squidcloud/backend';

class SecurityService extends SquidService {
@secureCollection('users', 'read')
secureUsersRead(): boolean {
return this.isAuthenticated();
}
}

セキュリティデコレーターとパターンの全体像については、Security rules documentation を参照してください。ロールベースのアクセスパターンについては、RBAC documentation を参照してください。

エラーハンドリング

認証に失敗すると、Squid は 401 UNAUTHORIZED レスポンスを返します。よくある原因は次のとおりです。

  • トークンの期限切れ: getToken() が返したトークンが有効期限を過ぎています。Token caching セクションの例のように、更新を伴うトークンキャッシュを実装してください。
  • integration ID の不一致: SquidAuthProviderintegrationId が、Squid Console で設定した integration ID と一致していません。両方の値が完全に一致することを確認してください。
  • auth provider の設定不足: Squid Console に auth connector が追加されていない、または設定が誤っています(ドメイン、client ID などが違う)。
  • トークンが返されない: getToken()undefined を返すため、リクエストに auth 情報が送られていません。認証が必要なリクエストを行う前に、ユーザーがサインインしていることを確認してください。

認証問題をデバッグするには、次を確認してください。

  1. connector が Squid Console で正しく設定されている。
  2. setAuthProvider に渡す integrationId が Console の integration ID と完全に一致している。
  3. getToken() が有効で、期限切れではないトークンを返している。

ベストプラクティス

  • getToken() 内でトークンをキャッシュし、有効期限の少し前に更新して、認証プロバイダーへの不要な往復を避けます。
  • security rules では常に isAuthenticated() をチェックし、どのリソースへのアクセスを許可する前にも基本要件として用います。
  • ユーザー向け機能には Bearer tokens を使用し、backend サービスやスクリプトには API keys を使用します。
  • データベース、API、ストレージ、キューなど、すべての入口(entry points)を保護します。保護されていない入口があると、auth チェックを迂回されます。
  • assertIsAuthenticated() を使用して、手動でチェックしてスローするのではなく、明確なエラーで早期に失敗させます。