カスタム機能認証
項目一覧
Overview
カスタム関数認証プロバイダーを使用すると、サーバーレス関数を使用してカスタム認証フローを定義できます。 このプロバイダーを使用して、独自のユーザー認証ロジックを実装したり、外部の認証システムを統合したりできます。
カスタム機能認証を使用する場合
カスタム関数認証は、最も柔軟な形式の認証です。 ただし、認証フローを自分で手動で定義および構成する必要があります。
カスタム関数プロバイダーを定義する前に、代わりに組み込み認証プロバイダを 1 つ使用できるかどうかを検討してください。
次の場合は、アプリでカスタム関数プロバイダーを使用することを検討してください。
組み込みプロバイダーのない外部認証サービスを使用する場合。 サービスがJSON web token を使用する場合は、代わりにカスタムJSON web tokenプロバイダーを作成することを検討してください。
組み込みプロバイダーにある認証プロセスを超えて、認証プロセスをカスタマイズしたい場合。 たとえば、 サービスを使用して、デフォルトのメール/パスワード プロバイダー メールの代わりに、カスタマイズされた確認メールを送信できます。
重要
Atlas App Services は、カスタム関数プロバイダーのデータ検証または認証チェックを実行しません。
受信データを検証し、パスワードの要求など、認証システムが適切な認証チェックを実行していることを確認します。 2 要素認証 、または シングル サインオン トークン。
次の図は、カスタム関数のログオン プロセスを示しています。
認証機能
認証関数は、カスタム ユーザー認証コードを保持する JavaScript 関数です。 ユーザーがログインするたびにカスタム関数プロバイダーを通じて実行されます。
この関数は、ユーザー名やパスワードやアクセス トークンなど、ログイン時に提供されるデータを、外部認証システム内のユーザーを一意に識別する string にマッピングします。 たとえば、提供されたデータを使用して、HTTP 経由や npm のパッケージを使用して外部サービスにログインすることができます。
exports = async function (payload) { // 1. Parse the `payload` object, which holds data from the // FunctionCredential sent by the SDK. const { username, password } = payload; // 2. Create a new user or log in an existing user in the external // authentication service. // You can use a client library from npm const auth = require("fake-auth-service"); const user = await auth.login({ username, password }); // Or you can communicate directly over HTTP const userFromHttp = await context.http.post({ url: "https://example.com/auth/login", headers: { Authorization: ["Basic bmlja0BleGFtcGxlLmNvbTpQYTU1dzByZA=="], }, body: JSON.stringify({ username, password }), }); // 3. Return a unique identifier for the user. Typically this is the // user's ID in the external authentication system or the _id of a // stored MongoDB document that describes them. // // !!! This is NOT the user's internal account ID for your app !!! return user.id; };
カスタム認証情報ペイロードの受信
関数に渡される payload
オブジェクトには、クライアントアプリのカスタム関数プロバイダーの認証情報に含まれていたデータが含まれています。 関数はクライアントアプリから提供された任意の値を受け入れるため、実際のフィールド名と値は 実装によって異なります。
Realm SDK を使用してカスタム認証情報payload
オブジェクトを作成する方法の例については、各 SDK のドキュメントを参照してください。
認証されたユーザー ID を返す
認証が成功した場合、関数はユーザーの一意の string 識別子を返します。 たとえば、外部認証システムで使用されるユーザー ID の値を返すことができます。 これはユーザーの外部 IDで、プロバイダーがカスタム システムからアプリの内部ユーザー アカウントにマッピングするために使用します。
重要
ユーザーの外部 IDは、ユーザー オブジェクトのid
フィールドとして公開されるユーザーの内部アカウント ID とは異なります。 ユーザーの内部 ID%%user.id
には、式ではcontext.user.id
、関数ではUser.id
、SDK では プロパティを使用してアクセスします。
既存のユーザーがすでに外部 ID に関連付けられている場合、プロバイダーはそのユーザーをログインします。
プロバイダーに特定の外部 ID のレコードがない場合、プロバイダーは新しいユーザー アカウントを作成し、カスタム関数プロバイダー ID を追加して、新しいユーザーをログインします。
カスタム関数プロバイダーの ID オブジェクトはユーザー オブジェクトに保存され、次のようになります。
{ "id": "<Internal User Account ID>", "identities": [ { "providerType": "custom-function", "id": "<External User ID>", } ] }
例
認証関数は、一意の外部 ID を string として返す必要があります。
return "5f650356a8631da45dd4784c"
また、外部 ID をid
値として含むオブジェクトを返すこともできます。
return { "id": "5f650356a8631da45dd4784c" }
ユーザーの表示名を定義する場合は、返された オブジェクトのname
フィールドで定義します。
return { "id": "5f650356a8631da45dd4784c", "name": "James Bond" }
失敗した認証に対するエラーのスロー
ユーザーが無効な認証情報を提供した場合、または関数がユーザーの認証に失敗した場合、 はわかりやすいメッセージを表示してエラーをスローします。 SDK に添付された メッセージを含む401 - Unauthorized
エラーが返されます。
const auth = require("some-external-auth-system"); try { const user = await auth.login(payload); return user.id; } catch (err) { throw new Error(`Authentication failed with reason: ${err.message}`); }
カスタム関数プロバイダーを設定する
サポートされている任意の配置方法を使用して、カスタム関数認証を設定できます。
認証関数を定義する
プロバイダーは通常の関数を使用して認証を処理します。 この関数は、ユーザーを識別するための一意の外部ID stringを返します。
新しい認証関数を定義するには、次の手順に従います。
Functionドロップダウンをクリックし、New Function を選択します。
関数の名前を入力します。 この名前は、アプリケーション内のすべての関数間で一意である必要があります。
関数エディターでソースコードを定義します。
クリック Save
認証関数を定義する
プロバイダーは通常の関数を使用して認証を処理します。 この関数は、ユーザーを識別するための一意の外部ID stringを返します。 ユーザー。
認証関数のコードをfunctions
ディレクトリに保存します。
touch functions/handleCustomFunctionAuthentication.js
プロバイダー構成ファイルの追加
カスタム関数認証プロバイダを有効にして構成するには、 /auth/providers.json
でそのための構成オブジェクトを定義します。
カスタム関数プロバイダーの構成は次の形式になります。
{ "custom-function": { "name": "custom-function", "type": "custom-function", "config": { "authFunctionName": "<Authentication Function Name>" }, "disabled": false } }
カスタムユーザーデータの構成
MongoDB Atlas コレクション内のカスタム データを、アプリ内のユーザー アカウントに関連付けることができます。 これは、ユーザーのデータにアクセスする必要があるが、カスタム関数プロバイダーを使用する必要がない場合に役立ちます。
ユーザーのカスタム データ ドキュメントには任意のデータを含めることができます。 カスタム関数プロバイダーを使用するアプリの場合、ユーザーの内部ユーザーアカウント ID と外部 ID の両方を保存することをお勧めします。
たとえば、次の形式を使用できます。
{ "_id": "<Generated ObjectId>", "user_id": "<Internal User ID>", "external_id": "<External User ID>" }
カスタム関数プロバイダー ユーザー用のカスタム ユーザー ドキュメントを作成するには、次のアプローチを使用できます。
連結クラスター内のコレクションのカスタム ユーザー データを構成します。 [ ユーザー ID ] フィールドには、ユーザーの内部アカウント ID が保存されます。
/auth/custom_user_data.json{ "mongo_service_name": "mongodb-atlas", "database_name": "myApp", "collection_name": "users", "user_id_field": "user_id", "enabled": true } カスタム関数認証プロバイダを構成し、認証関数から一意の外部ユーザー ID を返します。 App Services は、ユーザーの
custom-function
ID のid
フィールドにこの ID を保存します。exports = async function handleCustomFunctionAuth(payload) { const auth = require("some-external-auth-system"); const user = await auth.login(payload); return user.id; }; custom-function
プロバイダーからのCREATE
イベントをリッスンする認証triggerを設定します。 trigger 関数で、ユーザーの内部 ID と外部 ID の両方を含む新しいドキュメントをカスタム ユーザー データ コレクションに追加します。exports = async function onNewCustomFunctionUser({ user }) { // This is the user's internal account ID that was generated by your app const internalId = user.id; // This is the external ID returned from the authentication function const customFunctionIdentity = user.identities.find((id) => { return id.provider_type === "custom-function"; }); const externalId = customFunctionIdentity.id; // Create a custom user data document for the user const mdb = context.services.get("mongodb-atlas"); const users = mdb.db("myApp").collection("users"); return await users.insertOne({ // Include both the internal ID and external ID user_id: internalId, external_id: externalId, // Add any other data you want to include created_at: new Date(), }); };
Realm SDK からログイン
クライアントアプリケーションからログインするには、ログインペイロードデータを含むカスタム関数認証情報を使用します。
例については、特定の SDK のドキュメントを参照してください。