Adicionar autenticação ao seu aplicativo Android (Kotlin/Java)
Este guia mostrará como integrar o Logto ao seu aplicativo Android.
- O exemplo é baseado no sistema View e no View Model, mas os conceitos são os mesmos ao usar o Jetpack Compose.
- O exemplo está escrito em Kotlin, mas os conceitos são os mesmos para Java.
- Projetos de exemplo em Kotlin e Java estão disponíveis em nosso repositório SDK.
- O vídeo tutorial está disponível em nosso canal do YouTube.
Pré-requisitos
- Uma conta no Logto Cloud ou um Logto auto-hospedado.
- Um aplicativo nativo Logto criado.
- Um projeto de aplicativo Android em Kotlin.
Instalação
O nível mínimo de API do Android suportado pelo Logto Android SDK é o nível 24.
O Logto Android SDK está disponível em duas versões principais:
- v3: Abre a experiência de login em Chrome Custom Tabs (o navegador do sistema), o que permite o login com passkey e compartilha a sessão do navegador. Observe que a v3 remove o suporte para os conectores WeChat (Nativo) e Alipay (Nativo); você pode usar WeChat (Web) e Alipay (Web) em vez disso, que funcionam através do navegador. Se você depende dos conectores nativos, permaneça na v2.
- v2: Abre a experiência de login em um WebView incorporado, o que é necessário para os conectores sociais nativos, mas não suporta login com passkey (WebView não suporta WebAuthn, o padrão subjacente das passkeys).
Este guia cobre ambas as versões. Escolha sua versão nas abas abaixo, e a escolha será mantida sincronizada ao longo deste guia.
Antes de instalar o Logto Android SDK, certifique-se de que mavenCentral() está adicionado à configuração do seu repositório no arquivo de build do projeto Gradle:
dependencyResolutionManagement {
repositories {
mavenCentral()
}
}
Adicione o Logto Android SDK às suas dependências:
- v3
- v2
Use a versão mais recente da v3 como versão:
- Kotlin
- Groovy
dependencies {
implementation("io.logto.sdk:android:3.0.0")
}
dependencies {
implementation 'io.logto.sdk:android:3.0.0'
}
- Kotlin
- Groovy
dependencies {
implementation("io.logto.sdk:android:2.0.3")
}
dependencies {
implementation 'io.logto.sdk:android:2.0.3'
}
Como o SDK precisa de acesso à internet, você precisa adicionar a seguinte permissão ao seu arquivo AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- adicionar permissão de internet -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- outras configurações... -->
</manifest>
Integração
Inicializar LogtoClient
Crie um LogtoViewModel.kt e inicie o LogtoClient neste view model:
//...com outros imports
import io.logto.sdk.android.LogtoClient
import io.logto.sdk.android.type.LogtoConfig
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
private val logtoConfig = LogtoConfig(
endpoint = "<your-logto-endpoint>",
appId = "<your-app-id>",
scopes = null,
resources = null,
usingPersistStorage = true,
)
private val logtoClient = LogtoClient(logtoConfig, application)
companion object {
val Factory: ViewModelProvider.Factory = object : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(
modelClass: Class<T>,
extras: CreationExtras
): T {
// Obtenha o objeto Application dos extras
val application = checkNotNull(extras[APPLICATION_KEY])
return LogtoViewModel(application) as T
}
}
}
}
em seguida, crie um LogtoViewModel para o seu MainActivity.kt:
//...com outros imports
class MainActivity : AppCompatActivity() {
private val logtoViewModel: LogtoViewModel by viewModels { LogtoViewModel.Factory }
//...outros códigos
}
Configurar URI de redirecionamento
Antes de entrarmos nos detalhes, aqui está uma visão geral rápida da experiência do usuário final. O processo de login pode ser simplificado da seguinte forma:
- Seu app invoca o método de login.
- O usuário é redirecionado para a página de login do Logto. Para aplicativos nativos, o navegador do sistema é aberto.
- O usuário faz login e é redirecionado de volta para seu app (configurado como o URI de redirecionamento).
Sobre o login baseado em redirecionamento
- Este processo de autenticação segue o protocolo OpenID Connect (OIDC), e o Logto aplica medidas de segurança rigorosas para proteger o login do usuário.
- Se você tiver vários aplicativos, pode usar o mesmo provedor de identidade (Logto). Uma vez que o usuário faz login em um aplicativo, o Logto completará automaticamente o processo de login quando o usuário acessar outro aplicativo.
Para saber mais sobre a lógica e os benefícios do login baseado em redirecionamento, veja Experiência de login do Logto explicada.
Vamos mudar para a página de detalhes do Aplicativo no Logto Console. Adicione um URI de redirecionamento io.logto.android://io.logto.sample/callback e clique em "Salvar alterações".
No Android, o URI de redirecionamento segue o padrão: $(LOGTO_REDIRECT_SCHEME)://$(YOUR_APP_PACKAGE)/callback:
- O
LOGTO_REDIRECT_SCHEMEdeve ser um esquema personalizado no formato de domínio reverso. - O
YOUR_APP_PACKAGEé o nome do pacote do seu aplicativo.
Assumindo que você use io.logto.android como o esquema personalizado LOGTO_REDIRECT_SCHEME, e io.logto.sample como o nome do pacote do seu aplicativo, o URI de redirecionamento deve ser io.logto.android://io.logto.sample/callback.
- v3
- v2
Na v3, a experiência de login é aberta em uma Custom Tab (o navegador do sistema), e o redirecionamento é roteado de volta ao seu aplicativo por meio de um filtro de intent em nível de sistema operacional. Você precisa declarar o esquema do seu URI de redirecionamento com o placeholder de manifesto logtoRedirectScheme no arquivo de build do seu aplicativo:
- Kotlin
- Groovy
android {
defaultConfig {
manifestPlaceholders["logtoRedirectScheme"] = "io.logto.android"
}
}
android {
defaultConfig {
manifestPlaceholders.logtoRedirectScheme = 'io.logto.android'
}
}
Além disso, a v3 reforça o padrão do URI de redirecionamento por meio da correspondência do filtro de intent do Android, então um URI de redirecionamento que desvie do padrão nunca será entregue ao seu aplicativo:
- O esquema deve ser igual ao placeholder de manifesto
logtoRedirectScheme. - O host deve ser seu
applicationId. - O caminho deve ser
/callback.
Mantenha o esquema e o host em minúsculas, pois a correspondência do filtro de intent diferencia maiúsculas de minúsculas e os navegadores convertem o esquema para minúsculas.
Usar App Links em vez de um esquema personalizado?
Para usar Android App Links (um URI de redirecionamento https em um domínio que você possui) em vez do esquema personalizado:
-
Hospede o arquivo Digital Asset Links em
https://your.domain/.well-known/assetlinks.json, declarando seu application ID e as impressões digitais SHA-256 dos seus certificados de assinatura. Ao publicar com Play App Signing, você pode encontrar a impressão digital de release no Play Console em Configuração > Assinatura do app. O arquivo deve ser servido comoContent-Type: application/jsoncom HTTP 200 e sem redirecionamentos. -
Declare o intent filter de App Links na activity de recebimento de redirecionamento do SDK
io.logto.sdk.android.auth.logto.LogtoRedirectReceiverActivityno seu arquivoAndroidManifest.xml. Se você não usar o esquema personalizado, remova o filtro padrão do SDK comtools:node="removeAll", e o placeholder de manifestologtoRedirectSchemenão será mais necessário:AndroidManifest.xml<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><application><activity android:name="io.logto.sdk.android.auth.logto.LogtoRedirectReceiverActivity"><!-- Omitir esta linha para manter o redirecionamento por esquema personalizado funcionando em paralelo. --><intent-filter tools:node="removeAll" /><intent-filter android:autoVerify="true"><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><data android:scheme="https" android:host="your.domain" android:path="/callback" /></intent-filter></activity></application></manifest> -
Adicione
https://your.domain/callbackcomo um URI de redirecionamento (e, se for usado para logout, um URI de redirecionamento pós-logout) na página de detalhes do aplicativo no Logto Console, e passe-o parasignIn/signOut.
Lembre-se de que o callback agora é uma URL real no seu domínio, então sirva uma página de fallback lá (por exemplo, um botão "Retornar ao app") para navegadores que não abrem App Links em um redirecionamento do servidor. O botão só precisa apontar para a URL atual (por exemplo, definindo href para window.location.href): os parâmetros de autorização estão na query string, e um clique iniciado pelo usuário dá à mesma URL outra chance de ser roteada para o seu app. No Android 12+ um domínio não verificado nunca abre o app, então um assetlinks.json quebrado falha silenciosamente. Você pode verificar o estado da verificação com adb shell pm get-app-links <applicationId>.
Nenhuma configuração adicional é necessária. A experiência de login é aberta em um WebView embutido, e o SDK intercepta o redirecionamento dentro do WebView.
Implementar login e logout
Antes de chamar logtoClient.signIn, certifique-se de que você configurou corretamente o URI de redirecionamento no Admin Console.
Você pode usar logtoClient.signIn para autenticar o usuário e logtoClient.signOut para desconectar o usuário.
- v3
- v2
Na v3, logtoClient.signOut realiza uma saída completa: limpa as credenciais locais, revoga o token de atualização (refresh token) e encerra a sessão Logto abrindo o endpoint de encerramento de sessão no navegador. O navegador então retorna ao seu app através do post sign-out redirect URI. Antes de usar, acesse a página de detalhes do aplicativo no Logto Console, adicione o post sign-out redirect URI io.logto.android://io.logto.sample/callback e clique em "Salvar alterações". O post sign-out redirect URI segue o mesmo padrão do redirect URI, e seu esquema também deve corresponder ao placeholder de manifesto logtoRedirectScheme.
Por exemplo, em um app Android:
//...com outros imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...outros códigos
// Adicione um live data para observar o status de autenticação
private val _authenticated = MutableLiveData(logtoClient.isAuthenticated)
val authenticated: LiveData<Boolean>
get() = _authenticated
fun signIn(context: Activity) {
logtoClient.signIn(context, "io.logto.android://io.logto.sample/callback") { logtoException ->
logtoException?.let { println(it) }
// Atualize o live data
_authenticated.postValue(logtoClient.isAuthenticated)
}
}
fun signOut(context: Activity) {
logtoClient.signOut(context, "io.logto.android://io.logto.sample/callback") { logtoException ->
logtoException?.let { println(it) }
// Atualize o live data
_authenticated.postValue(logtoClient.isAuthenticated)
}
}
}
Depois, chame os métodos signIn e signOut em sua activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...outros códigos
// Suponha que você tenha um botão com id "sign_in_button" no seu layout
val signInButton = findViewById<Button>(R.id.sign_in_button)
signInButton.setOnClickListener {
logtoViewModel.signIn(this)
}
// Suponha que você tenha um botão com id "sign_out_button" no seu layout
val signOutButton = findViewById<Button>(R.id.sign_out_button)
signOutButton.setOnClickListener {
if (logtoViewModel.authenticated) { // Verifique se o usuário está autenticado
logtoViewModel.signOut(this)
}
}
// Observe o status de autenticação para atualizar a UI
logtoViewModel.authenticated.observe(this) { authenticated ->
if (authenticated) {
// O usuário está autenticado
signInButton.visibility = View.GONE
signOutButton.visibility = View.VISIBLE
} else {
// O usuário não está autenticado
signInButton.visibility = View.VISIBLE
signOutButton.visibility = View.GONE
}
}
}
}
- Você também pode chamar
logtoClient.signOut(context)sem um post sign-out redirect URI. Nenhuma configuração no Console é necessária nesse caso: o navegador mostra a página de saída do Logto, e o usuário retorna ao app fechando-a manualmente. - Se nenhum contexto de UI estiver disponível, você pode chamar
logtoClient.clearCredentialspara limpar as credenciais locais e revogar o token de atualização (refresh token). Observe que isso mantém a sessão Logto no navegador, então o próximosignInpode autenticar o usuário silenciosamente através dessa sessão.
Por exemplo, em um app Android:
//...com outros imports
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...outros códigos
// Adicione um live data para observar o status de autenticação
private val _authenticated = MutableLiveData(logtoClient.isAuthenticated)
val authenticated: LiveData<Boolean>
get() = _authenticated
fun signIn(context: Activity) {
logtoClient.signIn(context, "io.logto.android://io.logto.sample/callback") { logtoException ->
logtoException?.let { println(it) }
// Atualize o live data
_authenticated.postValue(logtoClient.isAuthenticated)
}
}
fun signOut() {
logtoClient.signOut { logtoException ->
logtoException?.let { println(it) }
// Atualize o live data
_authenticated.postValue(logtoClient.isAuthenticated)
}
}
}
Depois, chame os métodos signIn e signOut em sua activity:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...outros códigos
// Suponha que você tenha um botão com id "sign_in_button" no seu layout
val signInButton = findViewById<Button>(R.id.sign_in_button)
signInButton.setOnClickListener {
logtoViewModel.signIn(this)
}
// Suponha que você tenha um botão com id "sign_out_button" no seu layout
val signOutButton = findViewById<Button>(R.id.sign_out_button)
signOutButton.setOnClickListener {
if (logtoViewModel.authenticated) { // Verifique se o usuário está autenticado
logtoViewModel.signOut()
}
}
// Observe o status de autenticação para atualizar a UI
logtoViewModel.authenticated.observe(this) { authenticated ->
if (authenticated) {
// O usuário está autenticado
signInButton.visibility = View.GONE
signOutButton.visibility = View.VISIBLE
} else {
// O usuário não está autenticado
signInButton.visibility = View.VISIBLE
signOutButton.visibility = View.GONE
}
}
}
}
Ponto de verificação: Teste seu aplicativo
Agora, você pode testar seu aplicativo:
- Execute seu aplicativo, você verá o botão de login.
- Clique no botão de login, o SDK iniciará o processo de login e redirecionará você para a página de login do Logto.
- Após fazer login, você será redirecionado de volta para seu aplicativo e verá o botão de logout.
- Clique no botão de logout para limpar o armazenamento de tokens e sair.
Obter informações do usuário
Exibir informações do usuário
Para exibir as informações do usuário, você pode usar o método logtoClient.getIdTokenClaims(). Por exemplo, você pode obter as informações do usuário em um ViewModel e depois exibi-las em sua activity:
class LogtoViewModel(application: Application) : AndroidViewModel(application) {
// ...outros códigos
// Adicione um live data para observar as reivindicações do id token
private val _idTokenClaims = MutableLiveData<IdTokenClaims>()
val idTokenClaims: LiveData<IdTokenClaims>
get() = _idTokenClaims
fun getIdTokenClaims() {
logtoClient.getIdTokenClaims { logtoException, idTokenClaims ->
logtoException?.let { _logtoException.postValue(it) } ?: _idTokenClaims.postValue(idTokenClaims)
}
}
}
//...com outros imports
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
//...outros códigos
// Suponha que você tenha um TextView com id `user_info_text_view` no seu layout
val userInfoResponseTextView: TextView = findViewById(R.id.user_info_text_view)
logtoViewModel.userInfoResponse.observe(this) { userInfoResponse ->
userInfoResponseTextView.text = if (userInfoResponse !== null) {
val json = Gson().toJson(userInfoResponse, UserInfoResponse::class.java)
JSONObject(json).toString(2)
} else {
""
}
}
}
}
Solicitar reivindicações adicionais
Você pode perceber que algumas informações do usuário estão faltando no objeto retornado de logtoClient.getIdTokenClaims(). Isso ocorre porque OAuth 2.0 e OpenID Connect (OIDC) são projetados para seguir o princípio do menor privilégio (PoLP), e o Logto é construído com base nesses padrões.
Por padrão, reivindicações limitadas são retornadas. Se você precisar de mais informações, pode solicitar escopos adicionais para acessar mais reivindicações.
Uma "reivindicação (Claim)" é uma afirmação feita sobre um sujeito; um "escopo (Scope)" é um grupo de reivindicações. No caso atual, uma reivindicação é uma informação sobre o usuário.
Aqui está um exemplo não normativo da relação escopo - reivindicação:
A reivindicação "sub" significa "sujeito (Subject)", que é o identificador único do usuário (ou seja, ID do usuário).
O Logto SDK sempre solicitará três escopos: openid, profile e offline_access.
Para solicitar escopos adicionais, você pode passá-los para o objeto LogtoConfig. Por exemplo:
private val logtoConfig = LogtoConfig(
// ...outras configs
scopes = listOf("email", "phone"), // ou `listOf(UserScope.EMAIL, UserScope.PHONE)`
)
Então você pode acessar as reivindicações adicionais no valor retornado de logtoClient.getIdTokenClaims():
logtoClient.getIdTokenClaims { logtoException, idTokenClaims ->
println("IdTokenClaims:$idTokenClaims")
}
// Agora você pode acessar as reivindicações adicionais `claims.email`, `claims.phone`, etc.
Reivindicações que precisam de solicitações de rede
Para evitar o inchaço do Token de ID (ID token), algumas reivindicações requerem solicitações de rede para serem buscadas. Por exemplo, a reivindicação custom_data não está incluída no objeto do usuário, mesmo que seja solicitada nos escopos. Para acessar essas reivindicações, você pode usar o método logtoClient.fetchUserInfo():
logtoClient.fetchUserInfo {_, userInfoResponse ->
println("UserInfoResponse:$userInfoResponse")
}
// Agora você pode acessar a reivindicação `userInfo.custom_data`
Escopos e reivindicações
Logto utiliza as convenções de escopos e reivindicações (scopes and claims) do OIDC para definir os escopos e reivindicações para obtenção de informações do usuário a partir do token de ID (ID token) e do endpoint userinfo do OIDC. Tanto "escopo (Scope)" quanto "reivindicação (Claim)" são termos das especificações do OAuth 2.0 e OpenID Connect (OIDC).
Para reivindicações padrão do OIDC, a inclusão no token de ID é estritamente determinada pelos escopos solicitados. Reivindicações estendidas (como custom_data e organizations) podem ser configuradas adicionalmente para aparecer no token de ID através das configurações de Token de ID personalizado.
Aqui está a lista de escopos suportados e as reivindicações correspondentes:
Escopos OIDC padrão
openid (padrão)
| Nome da reivindicação | Tipo | Descrição |
|---|---|---|
| sub | string | O identificador único do usuário |
profile (padrão)
| Nome da reivindicação | Tipo | Descrição |
|---|---|---|
| name | string | O nome completo do usuário |
| username | string | O nome de usuário do usuário |
| picture | string | URL da foto de perfil do usuário final. Esta URL DEVE se referir a um arquivo de imagem (por exemplo, um arquivo de imagem PNG, JPEG ou GIF), em vez de uma página da Web contendo uma imagem. Observe que esta URL DEVE referenciar especificamente uma foto de perfil do usuário final adequada para exibição, em vez de uma foto arbitrária tirada pelo usuário final. |
| created_at | number | Momento em que o usuário final foi criado. O tempo é representado como o número de milissegundos desde a época Unix (1970-01-01T00:00:00Z). |
| updated_at | number | Momento em que as informações do usuário final foram atualizadas pela última vez. O tempo é representado como o número de milissegundos desde a época Unix (1970-01-01T00:00:00Z). |
Outras reivindicações padrão incluem family_name, given_name, middle_name, nickname, preferred_username, profile, website, gender, birthdate, zoneinfo e locale também serão incluídas no escopo profile sem a necessidade de solicitar o endpoint userinfo. Uma diferença em relação às reivindicações acima é que essas reivindicações só serão retornadas quando seus valores não forem vazios, enquanto as reivindicações acima retornarão null se os valores estiverem vazios.
Diferente das reivindicações padrão, as reivindicações created_at e updated_at usam milissegundos em vez de segundos.
email
| Nome da reivindicação | Tipo | Descrição |
|---|---|---|
string | O endereço de email do usuário | |
| email_verified | boolean | Se o endereço de email foi verificado |
phone
| Nome da reivindicação | Tipo | Descrição |
|---|---|---|
| phone_number | string | O número de telefone do usuário |
| phone_number_verified | boolean | Se o número de telefone foi verificado |
address
Consulte o OpenID Connect Core 1.0 para detalhes sobre a reivindicação de endereço.
Escopos marcados como (padrão) são sempre solicitados pelo SDK do Logto. As reivindicações sob escopos OIDC padrão são sempre incluídas no token de ID quando o escopo correspondente é solicitado — elas não podem ser desativadas.
Escopos estendidos
Os seguintes escopos são estendidos pelo Logto e retornarão reivindicações através do endpoint userinfo. Essas reivindicações também podem ser configuradas para serem incluídas diretamente no token de ID através de Console > Custom JWT. Veja Token de ID personalizado para mais detalhes.
custom_data
| Nome da reivindicação | Tipo | Descrição | Incluído no token de ID por padrão |
|---|---|---|---|
| custom_data | object | Os dados personalizados do usuário |
identities
| Nome da reivindicação | Tipo | Descrição | Incluído no token de ID por padrão |
|---|---|---|---|
| identities | object | As identidades vinculadas do usuário | |
| sso_identities | array | As identidades SSO vinculadas do usuário |
roles
| Nome da reivindicação | Tipo | Descrição | Incluído no token de ID por padrão |
|---|---|---|---|
| roles | string[] | Os papéis do usuário | ✅ |
urn:logto:scope:organizations
| Nome da reivindicação | Tipo | Descrição | Incluído no token de ID por padrão |
|---|---|---|---|
| organizations | string[] | Os IDs das organizações às quais o usuário pertence | ✅ |
| organization_data | object[] | Os dados das organizações às quais o usuário pertence |
Essas reivindicações de organização também podem ser recuperadas via endpoint userinfo ao usar um token opaco. No entanto, tokens opacos não podem ser usados como tokens de organização para acessar recursos específicos da organização. Veja Token opaco e organizações para mais detalhes.
urn:logto:scope:organization_roles
| Nome da reivindicação | Tipo | Descrição | Incluído no token de ID por padrão |
|---|---|---|---|
| organization_roles | string[] | Os papéis da organização aos quais o usuário pertence no formato <organization_id>:<role_name> | ✅ |
Recursos de API e organizações
Recomendamos ler 🔐 Controle de Acesso Baseado em Papel (RBAC) primeiro para entender os conceitos básicos do RBAC do Logto e como configurar corretamente os recursos de API.
Configurar cliente Logto
Depois de configurar os recursos de API, você pode adicioná-los ao configurar o Logto em seu aplicativo:
val logtoConfig = LogtoConfig(
//...other configs
resources = listOf("https://shopping.your-app.com/api", "https://store.your-app.com/api"), // Adicionar recursos de API
)
Cada recurso de API tem suas próprias permissões (escopos).
Por exemplo, o recurso https://shopping.your-app.com/api tem as permissões shopping:read e shopping:write, e o recurso https://store.your-app.com/api tem as permissões store:read e store:write.
Para solicitar essas permissões, você pode adicioná-las ao configurar o Logto em seu aplicativo:
val logtoConfig = LogtoConfig(
// ..other configs
scopes = listOf("shopping:read", "shopping:write", "store:read", "store:write"),
resources = listOf("https://shopping.your-app.com/api", "https://store.your-app.com/api"),
)
Você pode notar que os escopos são definidos separadamente dos recursos de API. Isso ocorre porque Resource Indicators for OAuth 2.0 especifica que os escopos finais para a solicitação serão o produto cartesiano de todos os escopos em todos os serviços de destino.
Assim, no caso acima, os escopos podem ser simplificados a partir da definição no Logto, ambos os recursos de API podem ter escopos read e write sem o prefixo. Então, na configuração do Logto:
val logtoConfig = LogtoConfig(
// ...other configs
scopes = listOf("read", "write"),
resources = listOf("https://shopping.your-app.com/api", "https://store.your-app.com/api"),
)
Para cada recurso de API, ele solicitará os escopos read e write.
Não há problema em solicitar escopos que não estão definidos nos recursos de API. Por exemplo, você pode solicitar o escopo email mesmo que os recursos de API não tenham o escopo email disponível. Escopos indisponíveis serão ignorados com segurança.
Após o login bem-sucedido, o Logto emitirá os escopos apropriados para os recursos de API de acordo com os papéis do usuário.
Buscar token de acesso para o recurso de API
Para buscar o token de acesso para um recurso de API específico, você pode usar o método getAccessToken:
logtoClient.getAccessToken("https://shopping.your-app.com/api") { logtoException, accessToken ->
logtoException?.let { println(it) }
accessToken?.let { println(it) }
}
Este método retornará um token de acesso JWT que pode ser usado para acessar o recurso de API quando o usuário tiver as permissões relacionadas. Se o token de acesso em cache atual tiver expirado, este método tentará automaticamente usar um token de atualização para obter um novo token de acesso.
Buscar tokens de organização
Se organização é um conceito novo para você, por favor, leia 🏢 Organizações (Multi-tenancy) para começar.
Você precisa adicionar o escopo UserScope.Organizations ao configurar o cliente Logto:
val logtoConfig = LogtoConfig(
// ...other configs
scopes = listOf(UserScope.Organizations),
)
Uma vez que o usuário esteja autenticado, você pode buscar o token de organização para o usuário:
// Substitua o parâmetro por um ID de organização válido.
// IDs de organização válidos para o usuário podem ser encontrados na reivindicação do token de ID `organizations`.
logtoClient.getOrganizationToken("organization-id") { logtoException, organizationToken ->
logtoException?.let { println(it) }
organizationToken?.let { println(it) }
}
// ou
logtoClient.getOrganizationTokenClaims("organization-id") { logtoException, claims ->
logtoException?.let { println(it) }
claims?.let { println(it) }
}
Recursos de API da organização (Organization API resources)
Para buscar um token de acesso para um recurso de API em uma organização, você pode usar o método getAccessToken com o recurso de API e o ID da organização como parâmetros:
logtoClient.getAccessToken(
'https://shopping.your-app.com/api',
organizationId
) { logtoException, accessToken ->
println("AccessToken:$accessToken")
}