Autenticação de função personalizada
Nesta página
- Visão geral
- Quando usar a autenticação de função personalizada
- A função de autenticação
- Receber uma carga de credencial personalizada
- Retornar um ID de usuário autenticado
- Lançar um erro por falha na autenticação
- Configurar o provedor de funções personalizadas
- Configurar dados de usuário personalizados
- Fazer login a partir de um SDK do Realm
Visão geral
O fornecedor de autenticação de função personalizado permite definir um fluxo de autenticação personalizado usando uma função sem servidor. Você pode usar esse fornecedor para implementar sua própria lógica de autenticação de usuário ou integrar um sistema de autenticação externo.
Quando usar a autenticação de função personalizada
A autenticação de função personalizada é a forma mais flexível de autenticação. No entanto, também exige que você mesmo defina e configure o fluxo de autenticação.
Antes de definir um fornecedor de função personalizado, confira se você pode usar um dos fornecedores de autenticação integrados.
Considere usar o fornecedor de funções personalizado no seu aplicativo se:
Você deseja usar um serviço de autenticação externo que não tenha um fornecedor integrado. Se o serviço usa JSON web tokens, considere a possibilidade de criar um fornecedor JWT personalizado.
Você deseja personalizar o processo de autenticação além do que está disponível em um fornecedor integrado. Por exemplo, você pode usar um serviço para enviar e-mails de confirmação personalizados em vez dos e-mails padrão do fornecedor de e-mail/senha.
Importante
O Atlas App Services não realiza nenhuma validação de dados ou verificação de autenticação para o fornecedor de função personalizada.
Certifique-se de validar os dados de entrada e de que o sistema de autenticação execute verificações de autenticação apropriadas, como asolicitação de uma senha, autenticação de dois fatores , ou um único login token.
O diagrama a seguir mostra o processo de logon da função personalizada:
A função de autenticação
A função de autenticação é uma função JavaScript que mantém seu código de autenticação de usuário personalizado. Ele é executado sempre que um usuário faz login por meio do fornecedor de função personalizada.
A função mapeia dados fornecidos no login, como nome de usuário e senha ou um token de acesso, para uma cadeia de caracteres que identifica exclusivamente o usuário em seu sistema de autenticação externo. Por exemplo, você pode usar os dados fornecidos para fazer login em um serviço externo por HTTP ou usar um pacote a partir de 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; };
Receber uma carga de credencial personalizada
O objeto payload
passado para a função contém dados que foram incluídos com a credencial do fornecedor de função personalizado no aplicativo cliente. A função aceita qualquer valor fornecido pelo seu aplicativo cliente, portanto, os nomes e valores reais dos campos dependem da sua implementação.
Para obter exemplos de como criar um objeto de credencial personalizada payload
usando o Realm SDKs, consulte a documentação para cada SDK:
Retornar um ID de usuário autenticado
Se a autenticação for bem-sucedida, a função deverá retornar um identificador de string único para o usuário. Por exemplo, você pode retornar o valor de ID do usuário usado pelo sistema de autenticação externo. Essa é a ID externa do usuário, que o fornecedor usa para mapear do seu sistema personalizado para as contas de usuário internas do aplicativo.
Importante
O ID externo do usuário não é igual ao ID da conta interna do usuário, exposto como o campo id
de um objeto de usuário. Você acessa o ID interno do usuário com %%user.id
em expressões, context.user.id
em funções e a propriedade User.id
nos SDKs.
Se um usuário existente já estiver associado ao ID externo, o fornecedor registrará esse usuário.
Se o fornecedor não tiver registro de um determinado ID externo, ele criará uma nova conta de usuário, adicionará uma identidade de fornecedor de função personalizada e fará o login do novo usuário.
O objeto de identidade para o provedor de função personalizada é armazenado no objeto de usuário e semelhante ao seguinte:
{ "id": "<Internal User Account ID>", "identities": [ { "providerType": "custom-function", "id": "<External User ID>", } ] }
Exemplo
A função de autenticação deve retornar um ID externo exclusivo como uma string:
return "5f650356a8631da45dd4784c"
Você também pode retornar um objeto que contém o ID externo como seu valor id
:
return { "id": "5f650356a8631da45dd4784c" }
Se você deseja definir um nome de exibição para o usuário, defina-o no campo name
do objeto retornado:
return { "id": "5f650356a8631da45dd4784c", "name": "James Bond" }
Lançar um erro por falha na autenticação
Se o usuário forneceu credenciais inválidas ou se a função falhar para autenticar o usuário, gere um erro com uma mensagem descritiva. Isso retorna um erro 401 - Unauthorized
com a mensagem anexada ao SDK.
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}`); }
Configurar o provedor de funções personalizadas
Você pode configurar a autenticação de função personalizada usando qualquer método de sistema compatível.
Defina a função de autenticação
O fornecedor usa uma função normal para lidar com a autenticação. A função deve retornar uma cadeia de caracteres de ID externa exclusiva para identificar o usuário.
Para definir uma nova função de autenticação:
Clique no menu suspenso Function e selecione New Function.
Insira um nome para a função. Este nome deve ser exclusivo entre todas as funções do seu aplicativo.
Define o código-fonte no editor de função.
Clique em Save
Distribuir o aplicativo atualizado
Para tornar a autenticação de função personalizada disponível para os aplicativos do cliente, distribua o seu aplicativo.
Clique em Deploy no menu de navegação à esquerda
Encontre o rascunho na tabela de histórico de implementação e clique em Review & Deploy Changes.
Revise a diferença de alterações e clique em Deploy.
Obtenha a versão mais recente da sua aplicação
Para extrair uma cópia local da versão mais recente do seu aplicativo, execute o seguinte:
appservices pull --remote="<Your App ID>"
Dica
Você também pode baixar uma cópia dos arquivos de configuração do seu aplicativo na tela Deploy > Export App na interface do usuário do App Services.
Defina a função de autenticação
O fornecedor usa uma função normal para lidar com a autenticação. A função deve retornar uma string de ID externa única para identificar o usuário. usuário.
Salve o código da função de autenticação no diretório functions
.
touch functions/handleCustomFunctionAuthentication.js
Adicionar um arquivo de configuração do provedor
Para habilitar e configurar o fornecedor de autenticação da Função Personalizada, defina um objeto de configuração para ele no /auth/providers.json
.
As configurações do fornecedor de função personalizada têm o seguinte formato:
{ "custom-function": { "name": "custom-function", "type": "custom-function", "config": { "authFunctionName": "<Authentication Function Name>" }, "disabled": false } }
Configurar dados de usuário personalizados
Você pode associar dados personalizados em uma coleção do MongoDB Atlas com contas de usuário em seu aplicativo. Isso pode ser útil se você geralmente precisar acessar os dados de um usuário, mas não é necessário usar o provedor de função personalizada.
O documento de dados personalizado de um usuário pode conter quaisquer dados. Para aplicações que usam o fornecedor de função personalizada, recomendamos armazenar os ID da conta de usuário interno e seu ID externo.
Por exemplo, você pode usar o seguinte formato:
{ "_id": "<Generated ObjectId>", "user_id": "<Internal User ID>", "external_id": "<External User ID>" }
Você pode usar a abordagem a seguir para criar documentos de usuário personalizados para usuários do fornecedor de funções personalizadas:
Configure dados de usuário personalizados para uma coleção em seu cluster vinculado. O campo ID do usuário armazena o ID interno da conta do usuário.
/auth/custom_user_data.json{ "mongo_service_name": "mongodb-atlas", "database_name": "myApp", "collection_name": "users", "user_id_field": "user_id", "enabled": true } Configure o fornecedor de autenticação de função personalizada e retorne um ID de usuário externo exclusivo da função de autenticação. O App Services armazena este ID no campo
id
da identidade do usuáriocustom-function
.exports = async function handleCustomFunctionAuth(payload) { const auth = require("some-external-auth-system"); const user = await auth.login(payload); return user.id; }; Configure um trigger de autenticação que escuta
CREATE
eventos do fornecedorcustom-function
. Na função de trigger, adicione um novo documento à coleção de dados do usuário personalizada que inclua o ID interno e o ID externo do usuário.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(), }); };
Fazer login a partir de um SDK do Realm
Para fazer login a partir de um aplicativo cliente, use uma credencial de função personalizada que contém seus dados de carga útil de login.
Por exemplo, consulte a documentação de um SDK específico: