После многих часов, потраченных на поиск лучшего решения для OAuth с помощью приложения Microsoft Azure и Expo, я решил поделиться с вами своими знаниями, чтобы вам не пришлось проводить бесконечные исследования из-за отсутствия документации.

Предпосылки

  1. Я предполагаю, что вы уже создали приложение Expo, если нет, вы можете найти инструкции здесь: https://docs.expo.dev/get-started/create-a-new-app/
  2. Приложение Azure было создано на портале Azure. https://portal.azure.com/

Время кодирования

Мы собираемся использовать пакет expo-auth-session для выполнения запросов к серверу Azure. Вот пример Экспо того, как это должно работать:



Чего они вам не объясняют, так это того, как получить access_token и token_id, необходимые для проверки контекст входа в систему на вашем внутреннем сервере.

Вам потребуется получить CLIENT_ID и TENET_ID на портале Azure.

// Endpoint
const discovery = useAutoDiscovery(
  `https://login.microsoftonline.com/${Constants.manifest.extra.AZURE_TENANT_ID}/v2.0`
);
// Request
const [azureRequest, azureResponse, promptAsyncAzure] = useAuthRequest(
  {
    clientId: Constants.manifest.extra.AZURE_CLIENT_ID,
    scopes: ['openid', 'profile', 'email', 'offline_access'],
    redirectUri: 'msauth.${APP_BUNDLE_ID}://auth',
    responseType: `${ResponseType.IdToken} ${ResponseType.Token}`,
    extraParams: {
      nonce: generateRandomString(),
    },
  },
  discovery
);

В redirectUri вы должны указать bundleId своего приложения.

responseType содержит два типа, разделенных пробелом, первый предназначен для получения tokenId, а второй один для accessToken.

Для получения tokenId вам необходимо передать случайную строку в качестве дополнительного параметра с ключом nonce.

Когда пользователь нажимает кнопку «Войти», мы должны вызвать функцию promptSyncAzure(), которая запустит окно аутентификации, чтобы пользователь мог пройти аутентификацию.

После успешной проверки подлинности ответ будет находиться в нашей переменной azureResponse.

Мы создадим useEffect и передадим переменную azureResponse в качестве зависимости, чтобы отслеживать изменения.

React.useEffect(() => {
  if (azureResponse?.type === 'success') {
    const { authentication } = azureResponse;
  }
}, [azureResponse]);

Теперь наш ответ будет содержать token_id и access_token из служб Azure.
Объект ответа должен выглядеть что-то вроде этого:

{
  "accessToken": "",
  "tokenType": "",
  "expiresIn": "",
  "scope": "",
  "state": "",
  "idToken": "",
  "issuedAt": ""
}

Вот и все!

Как бы просто это ни выглядело, может потребоваться много времени, чтобы в одиночку выяснить все необходимые параметры, чтобы получить нужный ответ при отсутствии документации.