Я использую SolidJS и создаю SPA (без серверного рендеринга). Для аутентификации я использую пакеты @aws-amplify/core и @aws-amplify/auth. В корне приложения я вызываю функцию Hub.listen:
Hub.listen('auth', ({ payload }) => console.info(payload));
В компоненте SignUp я вызываю Auth.federatedSignIn:
const SignUp = () => {
return (
<button onClick = {() => {
Auth.federatedSignIn({ provider: CognitoHostedUIIdentityProvider.Google });
}}>
Sign up
</button>
);
}
Я настроил Amplify как таковой:
Amplify.configure({
Auth: {
region: import.meta.env.VITE_AWS_REGION,
userPoolId: import.meta.env.VITE_AWS_POOL_ID,
userPoolWebClientId: import.meta.env.VITE_AWS_POOL_CLIENT_ID,
oauth: {
domain: import.meta.env.VITE_AUTH_URL,
responseType: 'code',
redirectSignIn: location.origin + '/account/external',
redirectSignOut: location.origin + '/my',
},
},
});
Когда я нажимаю на кнопку, меня перенаправляют на import.meta.env.VITE_AUTH_URL (просто вне моего приложения), я выбираю учетную запись, а затем возвращаюсь обратно на страницу /account/external. В то время я ожидаю консольный объект полезной нагрузки в веб-инструментах, но ничего нет. Я получаю его, когда звоню Auth.signOut(), поэтому я предполагаю, что правильно настроил Amplify и Hub подписан на канал auth.
Я думал, что Hub не может перехватывать какие-либо события, потому что после возврата приложение в основном снова рендерится в новом контексте, и Hub просто не может ничего перехватывать (события не отправляются из AWS?). Я попытался объявить функцию urlOpener под свойством oauth в конфиге и страница входа Google открылась в новой вкладке, но даже тогда я не смог получить никаких событий на сохраненной старой странице (из которой я вызывал Auth.federatedSignIn).
Вопросы:
Auth.federatedSignIn
, чтобы получить их обратно в Hub.listen
, чтобы я мог присоединиться к CognitoUser с данными, которые существовали на момент начала входа/регистрации (я хочу добавить новый тип входа в существующий пользователь)?Вот пример по первому вопросу. Просто убедитесь, что ваш прослушиватель установлен, прежде чем вызывать метод Auth.federatedSignIn().
export default class SignInService {
constructor(private landingFacade: LandingFacade) {
this.setupAuthListeners(); // Should be called at the top level.
}
private setupAuthListeners() {
Hub.listen('auth', ({ payload: { event, data } }) => {
switch (event) {
case 'signIn':
this.landingFacade.signInSuccess();
break;
case 'signIn_failure':
console.info('Sign in failure', data);
break;
case 'configured':
console.info('the Auth module is configured', data);
}
});
}
public async signIn(): Promise<void> {
await Auth.federatedSignIn();
}
}
Для второго: я буду использовать локальное состояние и устанавливать/запрашивать нужный вам объект.
Может быть, если вы более подробно опишете вторую проблему, я смогу дать вам некоторые подсказки.
Не понял, исправлена ли первая проблема. Если нет, это действительно зависит от того, где вы подписываетесь на слушателя. В моем случае я использую Angular, и его нужно вызывать откуда-то из контекста Angular. В приведенном выше примере это класс обслуживания, предоставляемый в Angular. Если я просто вызову его из того места, где вызывается Amplify.configure, он не сработает.
Вы помогли мне с первым заданием. Извините, если не ясно выразился. Подписываюсь на Hub прямо перед звонком в Amplify.configure и все работает. Чтобы решить вторую проблему, я использую sessionStorage, потому что он может сохранить данные после «обратного пути социальной аутентификации». Мне нужно уникальное хранилище для каждой открытой вкладки, и это вторая причина, по которой я выбрал sessionStorage. Возможно, вы имели в виду sessionStorage или localStorage под «местным состоянием». Если да, то я вдвойне благодарен :)
Спасибо за ответ. Я позвонил Hub.listen еще до Amplify.configure и получил parsingCallbackUrl и configured события на старте. К сожалению, локальное состояние не сохраняется после возврата со страницы oAuth провайдера.