Как хранить пользовательские данные в локальном хранилище с помощью плагина Capacitor's Storage?
Я пытаюсь добавить аутентификацию Firebase в свое приложение Angular.
Здесь signUp()
метод в моем AuthService
:
signUp(email: string, password: string, name: string) {
const userCredential = from(
firebase.auth().createUserWithEmailAndPassword(email, password)
.then(
(data) => {
let newUser: firebase.User = data.user;
newUser.updateProfile({
displayName: name,
photoURL: ''
}).then(() => {
firebase.firestore().collection('users').add({
userId: firebase.auth().currentUser.uid,
userName: firebase.auth().currentUser.displayName,
created: firebase.firestore.FieldValue.serverTimestamp()
});
});
Plugins.Storage.set({
key: 'userCredential',
value: newUser.uid
});
}
)
);
return userCredential;
}
С помощью этого метода я могу хранить newUser.uid
в локальном хранилище с помощью конденсатора Storage
плагин.
Но я хочу иметь возможность хранить ту же информацию, что и ниже (а именно localId
, email
, idToken
& expirationTime
:
login(email: string, password: string) {
return this.http.post<AuthResponseData>(
`firebaseUrl/v1/accounts:signInWithPassword?key=${
environment.firebaseAPIKey
}`,
{ email: email, password: password, returnSecureToken: true }
).pipe(tap(this.setUserData.bind(this)));
}
private setUserData(userData: AuthResponseData) {
const expirationTime = new Date(
new Date().getTime() + (+userData.expiresIn * 1000)
);
this._user.next(
new User(
userData.localId,
userData.email,
userData.idToken,
expirationTime
)
);
this.storeAuthData(userData.localId, userData.idToken, expirationTime.toISOString(), userData.email);
}
private storeAuthData(userId: string, token: string, tokenExpirationDate: string, email: string) {
const data = JSON.stringify({
userId: userId,
token: token,
tokenExpirationDate: tokenExpirationDate,
email: email
});
Plugins.Storage.set({ key: 'authData', value: data });
}
Может кто-нибудь сказать мне, как я могу получить эти 4 значения в моем signUp()
метод?
2 ответа
AuthService Login()
:
login(email: string, password: string) {
const userCredential = from(firebase.auth().signInWithEmailAndPassword(email, password).then(loggedInUser => {
Plugins.Storage.set({
key: 'userCredential',
value: loggedInUser.user.displayName
});
}));
return userCredential;
}
Auth Guard
:
userCredential;
canLoad(
route: Route,
segments: UrlSegment[]): Observable<boolean> | Promise<boolean> | boolean {
return Plugins.Storage.get({ key: 'userCredential' }).then(userCredential => {
this.userCredential = userCredential;
return this.autoLogin();
});
}
autoLogin() {
if (!this.userCredential || this.userCredential.value === null) {
this.router.navigateByUrl('login');
return false;
} else {
return true;
}
}
Согласно документам,.signInWithEmailAndPassword
возвращает Promise<UserCredential>
. Это означает, что есть какой-то результат, который вы можете сохранить в своем состоянии приложения, чтобы определить, кто является текущим пользователем.
Простой пример использования localStorage
:
login(email: string, password: string) {
return from(firebase.auth().signInWithEmailAndPassword(email, password));
}
После того, как вы позвонили login(..., ...)
, вы можете сохранить результат успеха в localStorage
:
localStorage.createItem('auth', userCredential)
Тогда, в своей охране, вы можете просто проверить, что в localStorage
:
canLoad(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
const userCredential = localStorage.getItem('auth');
// TODO: some validation step
return !!userCredential; // or the result of your validation
}
Другой способ сделать это - использовать ваши onAuthStateChanged
перезвонить:
firebase.auth().onAuthStateChanged(user => {
if (user) {
localStorage.setItem('auth', user);
console.log('Logged In User:', user);
} else {
console.log('Not Logged In');
this.router.navigateByUrl('login');
}
});
И затем, очевидно, когда пользователь выходит из системы или происходит что-то, что должно сделать сеанс недействительным, вы хотите удалить элемент из localStorage
:
localStorage.removeItem('auth');
Я бы порекомендовал принять что-то вроде NgRx или некоторого управления состоянием, чтобы помочь вам в управлении своим пользовательским состоянием, но вы можете обойтись локальным хранилищем, если хотите. Что касается безопасности, я предполагаю, что вы передаете какой-то ключ API или JWT с каждым запросом API для проверки пользователя.
В зависимости от того, насколько производительным вы хотите, чтобы охранник был, вы также можете заглянуть в API firebase, чтобы увидеть, есть ли у него какие-либо проверки, которые вы можете вызвать на месте в localstorage.
Примером может служить то, что внутри UserCredential
, у вас есть какой-то токен авторизации. Затем вы можете вызвать firebase с указанным токеном аутентификации, который должен вернуть истину / ложь, если это действительный токен или нет. Вы можете встроить это в свою охрану как более "прямой" способ проверки доступа пользователя. Но это также снизит производительность защиты, поскольку она должна выполнять вызов API каждый раз, когда используется защита. Локальное хранилище не представляет такой проблемы.