Português (Brasil)
  • SDK
  • OIDC

Implemente um SDK OIDC simples do lado do cliente

Logto oferece uma variedade de SDKs para diferentes plataformas. Além de nossos SDKs oficiais, incentivamos desenvolvedores da comunidade a criar seus próprios SDKs amigáveis ao usuário. Este artigo irá orientá-lo na construção de um SDK básico do lado do cliente para OIDC.

Simeng
Simeng
Developer

Introdução

Logto fornece a nossos desenvolvedores e grupos empresariais uma solução abrangente de Gerenciamento de Identidade e Acesso do Cliente (CIAM). Oferecemos uma ampla variedade de SDKs prontos para uso para diferentes plataformas e frameworks de aplicativos. Combinado com nosso serviço em nuvem Logto, você pode facilmente estabelecer um fluxo de autorização de usuário altamente seguro para seu aplicativo em questão de minutos. Como uma empresa que nasceu da comunidade de desenvolvedores, Logto abraça e valoriza nosso engajamento com a comunidade. Além dos SDKs oficialmente desenvolvidos pela Logto, continuamos a incentivar e acolher calorosamente os desenvolvedores da comunidade a contribuir com sua expertise criando SDKs mais diversos e amigáveis ao usuário, atendendo às necessidades únicas de várias plataformas e frameworks. Neste artigo, iremos demonstrar brevemente como implementar um SDK de autenticação padrão OIDC passo a passo.

Contexto

O fluxo do OpenID Connect (OIDC) é um protocolo de autenticação que se baseia no framework OAuth 2.0 para fornecer verificação de identidade e capacidades de single sign-on. Ele permite que os usuários se autentiquem com um aplicativo e obtenham autorização para acesso adicional a qualquer recurso privado de forma segura. Consulte as especificações OIDC para obter mais detalhes.

Fluxo de trabalho

Um fluxo de código de autorização padrão inclui as seguintes etapas:

Fluxo de autenticação

  1. Usuário inicia a solicitação de login: Um usuário anônimo chega ao seu aplicativo a partir de uma entrada pública. Tenta se autenticar e talvez solicitar mais acesso a um recurso protegido em um aplicativo ou serviço de terceiros.
  2. Autenticação do usuário: O aplicativo do cliente gera um URI de autenticação e envia uma solicitação para o servidor de autorização, que redireciona o usuário para sua página de login. O usuário interage com a página de login usando uma variedade de métodos de login e é autenticado pelo servidor de autorização.
  3. Manusear callback de login: Após uma autenticação bem-sucedida, o usuário será redirecionado de volta ao seu aplicativo com um authorization_code concedido. Este authorization_code contém todas as permissões relevantes vinculadas ao status de autenticação e dados de autorização solicitados.
  4. Troca de token: Solicitar troca de token usando o authorization_code extraído do endereço de redirecionamento acima. Em retorno:
    • id_token: Um JWT assinado digitalmente que contém informações de identidade sobre o usuário autenticado.
    • access_token: Um access_token opaco que pode ser usado para acessar o endpoint de informações básicas do usuário.
    • refresh_token: Token de credencial que permite ao usuário manter a troca contínua de um access_token

Fluxo de autorização

  1. Acessando informações do usuário: Para acessar mais informações do usuário, o aplicativo pode fazer solicitações adicionais ao endpoint UserInfo, utilizando o access_token opaco obtido no fluxo de troca de token inicial. Isso permite a recuperação de detalhes adicionais sobre o usuário, como seu endereço de e-mail ou foto de perfil.
  2. Concedendo acesso ao recurso protegido: Se necessário, o aplicativo pode fazer solicitações adicionais ao endpoint de troca de token, utilizando o refresh_token combinado com os parâmetros resource e scope, para obter um access_token dedicado para o usuário acessar o recurso alvo. Este processo resulta na emissão de um access_token formatado JWT contendo todas as informações de autorização necessárias para acessar o recurso protegido.

Implementação

Vamos seguir algumas estratégias de design dentro do nosso SDK JavaScript @logto/client para demonstrar o processo de implementação de um SDK simples para o seu próprio aplicativo do cliente. Por favor, tenha em mente que a estrutura de código detalhada pode variar dependendo do framework do cliente com o qual você está trabalhando. Sinta-se à vontade para escolher qualquer um dos SDKs oficiais do Logto como exemplo para o seu próprio projeto SDK.

Visualização

Construtor

O construtor deve receber um logtoConfig como entrada. Isso fornece todas as configurações necessárias para você estabelecer uma conexão de autenticação através deste SDK.

Dependendo da plataforma ou framework que você está usando para o SDK, você pode passar uma instância de armazenamento local persistente para o construtor. Esta instância de armazenamento será usada para armazenar todos os tokens e segredos relacionados à autorização.

Inicializar a autenticação do usuário

Antes de gerar um URL de solicitação de autenticação, é essencial concluir várias etapas de preparação para garantir um processo seguro.

Obter configurações OIDC do servidor de autorização

Definir um método privado `getOidcConfigs`` para obter as configurações OIDC do endpoint de descoberta do servidor de autorização. A resposta das configurações OIDC contém todas as informações de metadados que o cliente pode usar para interagir com o servidor de autorização, incluindo suas localizações de endpoints e as capacidades do servidor. (Consulte OAuth OAuth Authorization Server Metadata Specs para obter mais detalhes.)

Gerador PKCE

Um fluxo de validação PKCE(Proof Key for Code Exchange) é essencial para todas as trocas de código de autorização do cliente público. Ele atenua o risco do ataque de interceptação de authorization_code. Portanto, um code_challenge e code_verifier são necessários para todas as solicitações de autorização de aplicações cliente público (por exemplo, aplicativo nativo e SPA).

Os métodos de implementação podem variar dependendo das linguagens e frameworks que você está usando. Consulte a especificação code_challenge e code_verifier para as definições detalhadas.

Gerar parâmetro state

No fluxo de autorização, o parâmetro state é um valor gerado aleatoriamente que é incluído na solicitação de autorização enviada pelo cliente. Ele atua como uma medida de segurança para prevenir ataques de falsificação de solicitação inter-sites (CSRF).

Armazenar informações da sessão intermediária

Existem vários parâmetros que precisam ser preservados no armazenamento para fins de validação depois que o usuário se autenticar e for redirecionado de volta ao lado do cliente. Vamos implementar um método para definir esses parâmetros intermediários no armazenamento.

Login

Vamos reunir tudo implementado acima, definir um método que gera um URL de login do usuário e redireciona o usuário para o servidor de autorização para se autenticar.

Lidar com o callback de login do usuário

Na seção anterior, criamos um método de login que gera uma URL para a autenticação do usuário. Esta URL contém todos os parâmetros necessários necessários para iniciar um fluxo de autenticação a partir de um aplicativo cliente. O método redireciona o usuário para a página de login do servidor de autorização para autenticação. Após um login bem-sucedido, o usuário final será redirecionado de volta para a localização de redirect_uri fornecida acima. Todos os parâmetros necessários serão carregados no redirect_uri para completar os seguintes fluxos de troca de token.

Extrair e verificar o URL de callback

Esta etapa de validação é extremamente importante para prevenir qualquer forma de ataque forjado ao callback de autorização. O URL de callback DEVE ser cuidadosamente verificado antes de enviar uma solicitação de troca de código adicional ao servidor de autorização. Primeiramente, precisamos recuperar os dados de signInSession que armazenamos do armazenamento do aplicativo.

Então verifique o parâmetro URL do callback antes de enviar a solicitação de troca de token.

  • Use o redirectUri armazenado previamente para verificar se o callbackUri é o mesmo que enviamos para o servidor de autorização.
  • Use o state armazenado previamente para verificar se o estado retornado é o mesmo que enviamos para o servidor de autorização.
  • Verifique se há algum erro retornado pelo servidor de autorização
  • Verifique a existência do authorization_code retornado

Enviar a solicitação de troca de código

Como a etapa final do fluxo de autenticação do usuário, usaremos o authorization_code retornado para enviar uma solicitação de troca de token e obter os tokens de autorização necessários. Para mais detalhes sobre as definições dos parâmetros da solicitação, consulte a especificação de troca de token.

  • code: o authorization_code que recebemos do URI de callback
  • clientId: o ID do aplicativo
  • redirectUri: O mesmo valor é usado ao gerar a URL de login para o usuário.
  • codeVerifier: verificador de código PKCE. Semelhante ao redirectUri, o servidor de autorização irá comparar este valor com o que enviamos anteriormente, garantindo a validação da solicitação de troca de token de entrada.

Lidar com callback de login

Agrupando tudo o que temos. Vamos construir o método de manipulação do callback de login:

Como resultado, a solicitação de troca de token retornará os seguintes tokens:

  • id_token: OIDC idToken, um Token Web JSON (JWT) que contém informações de identidade sobre o usuário autenticado. id_token também pode ser usado como a Única Fonte de Verdade (SSOT) do status de autenticação de um usuário.
  • access_token: O código de autorização padrão retornado pelo servidor de autorização. Pode ser usado para chamar o endpoint de informações do usuário e recuperar informações do usuário autenticado.
  • refresh_token: (se o escopo offline_access estiver presente na solicitação de autorização): Este token de atualização permite que o aplicativo do cliente obtenha um novo access_token sem exigir que o usuário se reautentique, concedendo acesso a longo prazo aos recursos.
  • expires_in: A duração do tempo, em segundos, para a qual o access_token é válido antes de expirar.

Verificação do token ID

Verificar e extrair alegações do id_token é uma etapa crucial no processo de autenticação para garantir a autenticidade e integridade do token. Aqui estão as principais etapas envolvidas na verificação de um idToken.

  • Verificação da assinatura: O id_token é assinado digitalmente pelo servidor de autorização usando sua chave privada. O aplicativo do cliente precisa validar a assinatura usando a chave pública do servidor de autorização. Isso garante que o token não foi adulterado e que foi realmente emitido pelo servidor de autorização legítimo.
  • Verificação do emissor**:** Verifique se a alegação "iss" (emissor) no id_token corresponde ao valor esperado, indicando que o token foi emitido pelo servidor de autorização correto.
  • Verificação de público: Certifique-se de que a alegação "aud" (público) no id_token corresponde ao ID do cliente do aplicativo do cliente, garantindo que o token seja destinado ao cliente
  • Verificação de expiração: Verifique se a alegação "iat" (emitido em) no id_token não passou do tempo atual, garantindo que o token ainda seja válido. Como há custos de transação de rede, precisamos definir uma tolerância de tempo emitida ao validar a alegação iat do token recebido.

O id_token retornado é um Token Web JSON (JWT) padrão. Dependendo do framework que você está usando, você pode encontrar vários plugins convenientes de validação de tokens JWT para auxiliar na decodificação e validação do token. Para este exemplo, vamos utilizar jose em nosso SDK JavaScript para facilitar a validação e decodificação do token.

Obter informações do usuário

Após a autenticação bem-sucedida do usuário, as informações básicas do usuário podem ser obtidas do id_token OIDC emitido pelo servidor de autorização. No entanto, por razões de desempenho, o conteúdo do token JWT é limitado. Para obter informações de perfil de usuário mais detalhadas, os servidores de autorização compatíveis com OIDC oferecem um endpoint de informações do usuário fora da caixa. Este endpoint permite que você recupere dados adicionais do perfil do usuário solicitando escopos específicos do perfil do usuário.

Ao chamar um endpoint de troca de token sem indicar um recurso de API específico, por padrão, o servidor de autorização emitirá um access_token do tipo opaco. Este access_token só pode ser usado para acessar o endpoint de informações do usuário, permitindo a recuperação de dados básicos do perfil do usuário.

Obter token de acesso para autorização de recurso protegido

Na maioria dos casos, um aplicativo cliente não só requer autenticação do usuário, mas também precisa de autorização do usuário para acessar certos recursos protegidos ou endpoints de API. Aqui, usaremos o refresh_token obtido durante o login para adquirir access_token(s) especificamente concedidos para gerenciar recursos particulares. Isso nos permite obter acesso a essas APIs protegidas.

Resumo

Fornecemos implementações de métodos essenciais para o processo de autenticação e autorização do usuário no aplicativo do lado do cliente. Dependendo do seu cenário específico, você pode organizar e otimizar a lógica do SDK de acordo. Lembre-se de que podem existir variações devido a diferentes plataformas e frameworks.

Para obter detalhes adicionais, explore os pacotes SDK oferecidos pela Logto. Incentivamos mais usuários a se juntarem ao desenvolvimento e a se envolverem em discussões conosco. Seus feedback e contribuições são altamente valorizados à medida que continuamos a aprimorar e expandir as capacidades do SDK.

Apêndice

Escopos reservados

Escopos reservados do Logto que você precisará passar durante a solicitação de autenticação inicial. Esses escopos são ou OIDC-reservados ou Logto-reservados para completar um fluxo de autorização bem-sucedido.

Nome do escopoDescrição
openidNecessário para conceder id_token após uma autenticação bem-sucedida.
offline-accessNecessário para conceder um refresh_token que permite que seu aplicativo cliente troque e renove um access_token fora da tela.
profileNecessário para obter acesso às informações básicas do usuário

Logto Config

Nome da propriedadeTipoRequeridoDescriçãoValor padrão
appIdstringverdadeiroO identificador de aplicação único. Gerado pelo servidor de autorização para identificar o aplicativo cliente.
appSecretstringO segredo do aplicativo é usado, juntamente com o ID do aplicativo, para verificar a identidade do solicitante. É necessário para clientes confidenciais como aplicativos web Go ou Next.js, e opcional para clientes públicos como aplicativos nativos ou aplicativos de página única (SPAs)
endpointstringverdadeiroSeu endpoint raiz do servidor de autorização. Esta propriedade será amplamente usada para gerar solicitações de autorização.endpoint.
scopeslista de stringsIndica todos os escopos de recurso necessários que o usuário pode precisar ser concedidos para acessar quaisquer recursos protegidos dados.[reservedScopes]
resourceslista de stringsTodos os indicadores de recurso protegido que o usuário pode solicitar acesso

Métodos úteis

generateRandomString