arrow-return

Integrar o Project Expo com o Okta OpenID Login para iOS e Android

An image of André Souza, the author of this post
10 min de leitura

Partilhar


À medida que as aplicações móveis se tornam mais populares e generalizadas, é cada vez mais importante que os programadores incorporem métodos de autenticação seguros nas suas aplicações. Um desses métodos de autenticação é o OpenID, que permite aos utilizadores iniciar sessão em vários Web sites e aplicações utilizando um único conjunto de credenciais. Neste artigo, vamos explorar como integrar o Okta OpenID Login com uma aplicação móvel Project Expo para as plataformas iOS e Android.

O que é Okta?

Okta é uma plataforma de gestão de identidade baseada na nuvem que fornece serviços de autenticação e autorização seguros para aplicações web e móveis. Permite aos programadores integrar vários métodos de autenticação, incluindo nome de utilizador/palavra-passe, login social e autenticação multi-fator. O Okta fornece uma forma simples e segura de gerir a identidade do utilizador e o controlo de acesso, garantindo que apenas os utilizadores autorizados têm acesso a informações sensíveis.

O que é o Projecto Expo?

O Project Expo é uma ferramenta que permite aos programadores criar e publicar aplicações móveis multiplataforma utilizando o React Native. É uma excelente escolha para os programadores que pretendem criar aplicações móveis de forma rápida e eficiente, sem a necessidade de escrever código separado para cada plataforma.

Integração entre Okta OpenID e Login com Project Expo

Para integrar o Okta OpenID Login com uma aplicação móvel do Project Expo, temos de seguir alguns passos:

Passo nº1: Set up da Okta Account

O primeiro passo é inscrever-se numa conta Okta. Vá para o site da Okta e clique no botão “Get Started for Free”. Preencha os detalhes necessários e crie uma conta.

Depois de criar uma conta, faça login no Okta Developer Dashboard. A partir daí, clique em “Aplicativos” e, em seguida, em “Adicionar aplicativo”. Escolha “Nativo” como o tipo de aplicativo e clique em “Avançar”.

Na guia “Geral”, dê um nome ao seu aplicativo e carregue um logotipo, se desejar. No separador “Sign-in redirect URIs” (URIs de redireccionamento de início de sessão), escreva o url de redireccionamento (será o mesmo esquema que utilizaremos na configuração expo) “com.mydomain.myapp://callback” como método de início de sessão e, em seguida, clique em guardar.

Passo 1.1 Criar um user in OKTA

No painel esquerdo, clique em “Diretório”, ‘Pessoas’ e, em seguida, no painel oposto, clique em “Adicionar pessoa”

Preencha o texto inserido na Senha, selecione Definir pelo administrador, escreva uma senha e salve.

Passo nº 2: Configure Okta em app.json

Para configurar o Okta no Project Expo, precisamos de modificar o arquivo app.json. Veja como:

Primeiro, adicione as seguintes linhas ao objeto "expo" em app.json.

Substitua "com.yourcompany.yourapp" pelo seu próprio identificador de pacote ou nome do pacote.

Em seguida, adicione as seguintes linhas ao objeto "expo" em app.json:

{
  "expo": {
    "name": "okta",
    "slug": "okta",
    "scheme": "com.yourcompany.yourapp",
    "version": "1.0.0",
    "orientation": "portrait",
    "icon": "./assets/icon.png",
    "userInterfaceStyle": "light",
    "splash": {
      "image": "./assets/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "assetBundlePatterns": ["**/*"],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/adaptive-icon.png",
        "backgroundColor": "#ffffff"
      },
      "package": "com.yourcompany.yourapp"
    },
    "web": {
      "favicon": "./assets/favicon.png"
    }
  }
}

Estas linhas adicionam o esquema de URL personalizado, e o URL de retorno de chamada ao seu ficheiro app.json, o que é necessário para a autenticação do Okta.

Estas linhas concedem as permissões necessárias para que a sua aplicação aceda à internet e ao estado da rede.

Passo nº 3: Instalar Dependências

Para integrar o Okta na sua aplicação Project Expo, terá de instalar algumas dependências. Abra o terminal e navegue até ao diretório do seu projeto. Em seguida, execute os seguintes comandos:

npx expo install expo-auth-session

npx expo install expo-web-browser

npm install axios 

Estas dependências são necessárias para manipular a autenticação.

Passo nº 4: Implementar Okta Authentication

Agora que já configurámos o Okta no app.json e instalámos as dependências necessárias, podemos implementar a autenticação Okta na nossa aplicação Project Expo. Veja como:

Em App.js, vamos importar o que vamos utilizar:

import { StyleSheet, Button, SafeAreaView } from "react-native";
import { useState } from "react";

import axios from "axios";

import * as AuthSession from "expo-auth-session";
import * as WebBrowser from "expo-web-browser";

Depois adicionar as seguintes linhas:

//to ensure close login widget
WebBrowser.maybeCompleteAuthSession();

//connfiguration
const oktaConfig = {
  //ypur application id from okta
  clientId: "[your okta clientId]",
  //yout domain from okta
  domain: "https://[yout okta domain]",
  // yout domain + /oauth2/default
  issuerUrl: "https://[your okta domain]/oauth2/default",
  //callback configured in okta signin url
  callbackUrl: "com.yourcompany.yourapp://callback",
};

Agora configuramos os nossos ganchos para definir o ambiente de login.

  const [authState, setAuthState] = useState(null);

  const discovery = AuthSession.useAutoDiscovery(oktaConfig.issuerUrl);
  const redirectUri = AuthSession.makeRedirectUri({
    // For usage inbare and standalone
    path: "callback",
  });

Após efetuar estas alterações, poderá executar a sua aplicação com a autenticação Okta ativada. Quando o utilizador tocar no botão "Fazer login com Okta", a função loginWithOkta será chamada, gerando um URL de autorização e abrindo-o no browser da Expo utilizando o ptomptAsync. Isto solicitará que o utilizador insira as suas credenciais do Okta e autorize a sua aplicação a aceder às suas informações.

Após o utilizador autorizar a sua aplicação, será redirecionado para o redirectUri especificado. O módulo AuthSession processará automaticamente o redireccionamento e recuperará o código de autorização do URL. O código será então trocado por um token de acesso e um token de ID utilizando a API do Okta.

O token de acesso pode ser utilizado para fazer pedidos de API a recursos protegidos em nome do utilizador, enquanto o token de ID contém informações sobre o utilizador, como o seu endereço de e-mail e ID de utilizador.

Com esta implementação, a sua aplicação Expo poderá agora autenticar os utilizadores utilizando o serviço OpenID Connect do Okta. Pode personalizar a interface do utilizador do seu ecrã de login e lidar com erros conforme necessário para proporcionar uma experiência tranquila ao utilizador..

Vamos primeiro pegar no código de autorização

  const loginWithOkta = async () => {
    try {
      const request = new AuthSession.AuthRequest({
        clientId: oktaConfig.clientId,
        redirectUri: oktaConfig.callbackUrl,
        prompt: AuthSession.Prompt.SelectAccount,
        scopes: ["openid", "profile"],
        usePKCE: true,
        extraParams: {},
      });

      const result = await request.promptAsync(discovery);

      const code = JSON.parse(JSON.stringify(result)).params.code;
      setAuthState(result);

Agora podemos usar o código para termos o token e a informação do user.

      const tokenRequestParams = {
        code,
        clientId: oktaConfig.clientId,
        redirectUri: redirectUri,
        extraParams: {
          code_verifier: String(request?.codeVerifier),
        },
      };
      const tokenResult = await AuthSession.exchangeCodeAsync(
        tokenRequestParams,
        discovery
      );

      const accessToken = tokenResult.accessToken;

      // make an HTTP direct call to the Okta User Info endpoint of our domain
      const usersRequest = `${oktaConfig.issuerUrl}/v1/userinfo`;
      const userPromise = await axios.get(usersRequest, {
        headers: {
          Authorization: `Bearer ${accessToken}`,
        },
      });

      console.log("\n\nUser data:", userPromise.data);
      console.log("\n\nOkta Token: ", accessToken);
    } catch (error) {
      console.log("Error:", error);
    }
  };

Depois, dentro do retorno do componente, criamos um botão para chamar a função e criamos um estilo simples para a mesma.

 <SafeAreaView style={styles.container}>
      {authState ? (
        <Button title="Logout" onPress={() => setAuthState(null)} />
      ) : (
        <Button title="Login" onPress={loginWithOkta} />
      )}
 </SafeAreaView>

e aplique algum estilo no final do ficheiro.

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

O código completo do componente

import { StyleSheet, Button, SafeAreaView } from "react-native";
import { useState } from "react";

import axios from "axios";

import * as AuthSession from "expo-auth-session";
import * as WebBrowser from "expo-web-browser";

//to ensure close login widget
WebBrowser.maybeCompleteAuthSession();

//connfiguration
const oktaConfig = {
  //ypur application id from okta
  clientId: "[your okta clientID]",
  //yout domain from okta
  domain: "https://[your okta domain]",
  // yout domain + /oauth2/default
  issuerUrl: "https://[your okta domain]/oauth2/default",
  //callback configured in okta signin url
  callbackUrl: "com.yourcompany.yourapp://callback",
};

export default function App() {
  const [authState, setAuthState] = useState(null);

  const discovery = AuthSession.useAutoDiscovery(oktaConfig.issuerUrl);
  const redirectUri = AuthSession.makeRedirectUri({
    // For usage inbare and standalone
    path: "callback",
  });

  const loginWithOkta = async () => {
    try {
      const request = new AuthSession.AuthRequest({
        clientId: oktaConfig.clientId,
        redirectUri: oktaConfig.callbackUrl,
        prompt: AuthSession.Prompt.SelectAccount,
        scopes: ["openid", "profile"],
        usePKCE: true,
        extraParams: {},
      });

      const result = await request.promptAsync(discovery);

      const code = JSON.parse(JSON.stringify(result)).params.code;
      setAuthState(result);

      console.log(code);

      const tokenRequestParams = {
        code,
        clientId: oktaConfig.clientId,
        redirectUri: redirectUri,
        extraParams: {
          code_verifier: String(request?.codeVerifier),
        },
      };
      const tokenResult = await AuthSession.exchangeCodeAsync(
        tokenRequestParams,
        discovery
      );

      const accessToken = tokenResult.accessToken;

      // make an HTTP direct call to the Okta User Info endpoint of our domain
      const usersRequest = `${oktaConfig.issuerUrl}/v1/userinfo`;
      const userPromise = await axios.get(usersRequest, {
        headers: {
          Authorization: `Bearer ${accessToken}`,
        },
      });

      console.log("\n\nUser data:", userPromise.data);
      console.log("\n\nOkta Token: ", accessToken);
    } catch (error) {
      console.log("Error:", error);
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      {authState ? (
        <Button title="Logout" onPress={() => setAuthState(null)} />
      ) : (
        <Button title="Login" onPress={loginWithOkta} />
      )}
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

Para executar o projeto.

npx expo run:android     - for android
npx expo run:ios         - for ios


Subscreve a
nossa newsletter

Junta-te a 1.000+ pessoas e recebe semanalmente dicas,
boas práticas e insights.