Предисловие
Продолжение цикла по работе с 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');
}
};
Заключение
Вуаля. все готово! Теперь ваши пользователи смогут авторизовываться в вашем мобильном приложении.
Спасибо за внимание!