
Предисловие
Продолжение цикла по работе с Azure B2C. В данной статье я расскажу о том, как подключить аутентификацию на React Native.
Ссылки на связанные посты
- Часть 1: Создание и настройка приложений на Azure AD B2C
- Часть 2: Работа с Identity Framework Experience
- Часть 3: Подключение приложения React
- Часть 4: Подключение приложения React Native
- Часть 5: Подключение и настройка бэкэнда на .NET Core 3
ШАГ 1
Необходимо установить react-native-app-auth (npm i react-native-app-auth).
ШАГ 2
Открыть в Azure AD B2C ваше приложение. Во вкладке «Проверка подлинности» — нажать «Добавить платформу».
Необходимо выбрать Android и iOS.

После того, как вы создатие обе платформы вы полчите примерно такие данные:

ШАГ 3
Создать файл auth-provider.js в папке ./src
import { authorize, revoke, refresh } from 'react-native-app-auth'; const config = (page) => ({ // Найти issuer можно во вкладке "Обзор". Для этого нажмите кнопку "Конечные точки". // Также необходимо добавить "tfp" как показано в примере ниже. // В качестве параметра передаем нужную политику. issuer: `https://myapp.b2clogin.com/tfp/mycompany.onmicrosoft.com/${pages[page]}`, // ClientID вашего приложения Azure AD B2C clientId: '777aaa77a-7a77-7777-bb77-8888888aabc', scopes: ['openid'], // Обязательно укажите openid // Нужно для того, чтобы при повторной авторизации, пользователь мог // снова выбрать способ авторизации (Google, Facebook и т.д.) additionalParameters: { prompt: 'login' }, // URI перенаправления (Android) redirectUrl: 'msauth://com.myapp/asdasd%o293o4iro21342/', }); const logOutConfig = { clientId: '777aaa77a-7a77-7777-bb77-8888888aabc', serviceConfiguration: { revocationEndpoint: 'https://mycompany.b2clogin.com/mycompany.onmicrosoft.com/B2C_1A_SignIn/oauth2/v2.0/logout', }, }; // Используем отдельную политику для каждого действия const pages = { signIn: 'B2C_1A_SignIn', signUp: 'B2C_1A_SignUp', resetPassword: 'B2C_1A_PasswordReset', }; // Функция для получения данных с Azure. const getAzureData = async (page) => { try { const data = await authorize(config(page)); return data; } catch (e) { requestErrorHandler(e, 'azure authorize error'); } }; export const signIn = () => async (dispatch) => { const authMethod = 'signIn'; try { const data = await getAzureData(authMethod); dispatch(userRegistration(data, authMethod)); } catch (e) { requestErrorHandler(e, 'sign in error'); } }; export const azureLogOut = () => async (dispatch, getState) => { const { refreshToken } = getState().Authentication; try { await revoke(logOutConfig, { tokenToRevoke: refreshToken, sendClientId: true, }); dispatch(authActions.logOut()); } catch (e) { console.warn(e); } };
Где брать названия политик вы можете увидеть на скриншоте

ШАГ 4
Теперь нужно внести небольшие изменения в следующие файлы:
/android/app/build.gradle
defaultConfig { manifestPlaceholders = [ appAuthRedirectScheme: 'msauth' ] ... }
/ios/yourApp/Info.plist
<key>CFBundleURLTypes</key> <array> ... <dict> <key>CFBundleURLName</key> <string>com.yourApp</string> <key>CFBundleURLSchemes</key> <array> <string>msauth.com.yourApp</string> </array> </dict> </array>
ШАГ 5
Теперь нам необходимо сохранить токен, что бы не просить пользователя авторизоваться каждый раз когда он открывает ваше приложение. Для этого необходимо скачать redux-persist-sensitive-storage.
(npm i redux-persist-sensitive-storage).
import { compose, applyMiddleware, createStore } from "redux"; import { persistStore, persistCombineReducers } from "redux-persist"; import createSensitiveStorage from "redux-persist-sensitive-storage"; import reducers from "./reducers"; // where reducers is an object of reducers const storage = createSensitiveStorage({ keychainService: "myKeychain", sharedPreferencesName: "mySharedPrefs" }); const config = { key: "root", storage, }; const reducer = persistCombineReducers(config, reducers); function configureStore () { // ... let store = createStore(reducer); let persistor = persistStore(store); return { persistor, store }; }
ШАГ 6
Добавляем функции для обновления токена
export const autoSignIn = (params) => async (dispatch) => { try { const userData = await getRefreshedAzureUserData(params); await dispatch(openApplication(userData, params.authMethod)); } catch (e) { requestErrorHandler(e, 'auto sign in error'); } }; export const getRefreshedAzureUserData = async ({ refreshToken, authMethod }) => { try { const result = await refresh(config(authMethod), { refreshToken }); return result; } catch (e) { requestErrorHandler(e, 'get refresh token error'); } };
Заключение
Вуаля. все готово! Теперь ваши пользователи смогут авторизовываться в вашем мобильном приложении.
Спасибо за внимание!
