在Angular中实现firebaseUI,我缺少对“保持登录状态”选项的支持。
我意识到firebaseUI正在更新“注册”和“登录”的流程,并将这两个步骤合并为一个(https://github.com/firebase/firebaseui-web/issues/665#issuecomment-596197657)。但是,我找不到不能为用户提供选择正确的身份验证持久性(https://firebase.google.com/docs/auth/web/auth-state-persistence)的安全选项的借口。firebaseUI-angular部分记录了firebaseui.disableAutoSignIn(),但这不是切换,而是单向选项(https://github.com/RaphaelJenni/FirebaseUI-Angular#disable-autosign)。
所以,我在这里想念什么?如果在身份验证持久性隐式设置为LOCAL的情况下,如果在公共设备上访问其帐户,用户应如何保护其数据?
更新
经过两轮,我进入了一个有效的“保持登录状态”选项-但只能使用Google登录,而不能使用“电子邮件/链接”登录。
Email / Link的核心问题是,通过电子邮件发送的链接/ URL在新的浏览器选项卡中进行身份验证,在此过程中,很难启用身份验证持久性。通过电子邮件发送的链接/ URL进入firebaseapp.com,该网站进行身份验证并重定向到Angular应用程序。那么如何在此流程中传递用户的持久性选择呢?
firebaseUI-web + Angular沙箱的设置非常快:
app.module.ts:
import {AngularFireModule} from '@angular/fire';
import {AngularFireAuthModule} from '@angular/fire/auth';
import {environment} from 'src/environments/environment';
...
@NgModule({ ...
imports: [ ...
AngularFireModule.initializeApp(environment.firebaseConfig),
AngularFireAuthModule,
...
app.component.ts:
import { Component, OnInit } from '@angular/core';
import { AngularFireAuth } from '@angular/fire/auth';
import * as firebase from 'firebase/app';
import * as firebaseui from 'firebaseui';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
ui: firebaseui.auth.AuthUI; // firebaseUI reference
uiLinkUrl = false;
keepSignin = false;
constructor(public afAuth: AngularFireAuth) {}
ngOnInit() {
this.ui = new firebaseui.auth.AuthUI(firebase.auth());
if (this.ui.isPendingRedirect()) {
this.uiLinkUrl = true;
}
this.afAuth.authState.subscribe((response) => {
if (response) {
// update html element if not routing.
this.showFirebaseUI();
} else {
// only update persistence if signed out, and not reroute.
if (!this.uiLinkUrl) {
this.afAuth.auth.setPersistence(this.keepSignin ?
firebase.auth.Auth.Persistence.LOCAL :
firebase.auth.Auth.Persistence.SESSION);
}
this.uiLinkUrl = false;
this.showFirebaseUI();
}
});
}
toggleKeepSignin() {
this.keepSignin = !this.keepSignin;
this.afAuth.auth.setPersistence(this.keepSignin ?
firebase.auth.Auth.Persistence.LOCAL :
firebase.auth.Auth.Persistence.SESSION);
}
showFirebaseUI() {
// The start method will wait until the DOM is loaded.
this.ui.start('#firebaseui-auth-container', {
callbacks: {
uiShown: function () {
document.getElementById('loader').style.display = 'none';
},
signInSuccessWithAuthResult: function (authResult, redirectUrl) {
return false;
},
},
credentialHelper: firebaseui.auth.CredentialHelper.NONE,
signInFlow: 'popup',
signInOptions: [
{ provider: firebase.auth.GoogleAuthProvider.PROVIDER_ID,
customParameters: {prompt: 'select_account'} },
{ provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
signInMethod: firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD },
],
});
}
}
app.component.html:
<div *ngIf="afAuth.auth.currentUser">
<h1 style="color:#0a0;">Signed IN</h1>
<button (click)="afAuth.auth.signOut()">Sign Out</button>
</div>
<div *ngIf="!afAuth.auth.currentUser">
<h1 style="color:#a00;">Signed OUT</h1>
</div>
<div style="background:#222;" id="firebaseui-auth-container"></div>
<div id="loader">Loading...</div>
<div style="text-align:center;" (click)="toggleKeepSignin()">
<input type="checkbox" [checked]="keepSignin">Keep me signed in
</div>
我已经弄清楚了如何通过用户控制的持久性(“保持登录状态”选项来实现firebaseUI。解决方案涉及(1)仔细放置对auth.setPersistence()的调用,以及(2)在电子邮件/链接URL中传递用户的持久性选择。希望下面的描述和示例可以帮助其他需要最佳身份验证安全性的人。
我仍然想知道为什么这不是firebaseUI的一部分,因为管理方案有些棘手。在我看来,记住身份验证为默认值会危害数据安全,而将“用户体验摩擦”最小化的论点对此默认值无效(https://firebase.google.com/docs/auth/web/auth-state-persistence,第二段)。在公共设备上登录时,firebaseUI的持久身份验证会危及数据安全,因为它要求用户明确记住退出。
我已经设置了一个Stackblitz应用程序来说明将持久性作为用户选项进行FirebaseUI身份验证。https://stackblitz.com/edit/angular-5zmqq7。
P.S。关于可选的firebaseUI-angular替代方案(仅针对角度客户端),我看不到使用此潜在复杂额外层的任何原因,因为firebaseUI-web需要相同的最少代码来实现firebaseUI。实际上,使用firebaseUI-angular可能需要更困难地配置firebaseUI。请参阅app.component.ts以获取更多文档和沙箱说明。