使用Firebase Authentication在Angular应用中进行Google账户认证
引子(可忽略)
我先用Angular制作了一个简单的HTML页面。
只创建了登录页面,突然想到”认证要怎么做呢?”,作为一家处理谷歌技术的公司,暂时选择了谷歌认证。
不过,当我开始调查时发现需要使用OAuth等API,或者是付费的服务。。。
所以,我最终选择了Firebase。
(可能我应该早点注意到它)
然而,当我开始调查时,发现在Firebase中有很多”邮件地址和密码”的认证方式,但是使用”Google认证”的日语描述相对较少…(是我的调查方法有问题吗?!)
因此,我写了出来。
环境
macOS Mojave 10.14.6可以翻译为:苹果操作系统Mojave版本10.14.6。
※我实际上正在docker上运行Angular,但我觉得这与本次的话题无关,所以我没有提及。(Firebase的版本在哪里查看呢…)
$ ng version
@angular-devkit/architect 0.803.19
@angular-devkit/build-angular 0.803.19
@angular-devkit/build-optimizer 0.803.19
@angular-devkit/build-webpack 0.803.19
@angular-devkit/core 8.3.19
@angular-devkit/schematics 8.3.19
@angular/cdk 8.2.3
@angular/cli 8.3.19
@angular/fire 5.2.3
@angular/material 8.2.3
@ngtools/webpack 8.3.19
@schematics/angular 8.3.19
@schematics/update 0.803.19
rxjs 6.4.0
typescript 3.5.3
webpack 4.39.2
所需之物
Google アカウント(必須)
GCPアカウント(任意。なくても全然余裕)
ちょっと作りかけのAngularアプリ、もしくはAngularの簡単な知識(これはなくてもいけます。でも、あるとうれしい)
操作步骤
以下是大致的步骤:
1. 准备Firebase
2. 配置Firebase身份验证
3. 修改Angular应用程序
现在,我们按顺序来执行这些步骤。
准备Firebase
创建Firebase项目
首先,创建一个Firebase项目。
Firebase可以在这里找到。
点击「试用」按钮后,将跳转到Google账号验证页面。
在那里,使用提供的Google账号进行登录。
然后,屏幕会出现这样的画面。
这次,我们将创建一个新的项目。
对于与GCP项目关联的帐户,现有的GCP项目名称将作为选择项显示。
※※ 注意 ※※
如果关联的GCP项目需要付费,则会自动选择“按量计费”计划。
(不能选择免费计划,因为GCP需要付费,Firebase也需要付费吧?)
然而,即使是按量计费计划,也似乎有一些免费额度。详细信息请参阅以下内容。
Firebase费用
因为小豆正在使用的GCP项目是公司提供的计费沙盒,所以她有点担心,想选择免费套餐…
不过先放一边,我会立即创建。
项目名称基本上随便取一个好像都可以,我会随意取一个任意的名字。
※后来我意识到了,这将成为认证时的URL。
在接下来的屏幕上,有一个选择Google Analytics的屏幕。
按照推荐,将设置打开并继续,将会创建一个项目。
出现了这样的屏幕。
2. 設定身份驗證
激活谷歌认证
应用程序注册(获取认证信息)
為了在應用程式中使用認證功能,需要在應用程式中設定認證資訊。
在這裡,我們將取得認證資訊。
这次只是一个网页应用,所以我们要点击带有红色边框的标记。
给应用程序起一个看起来不错的昵称是不错的选择。
我认为给自己起一个能与其他应用程序区分开的名字是不错的建议。
3. 修复Angular应用
终于从这里开始进行应用程序的修正。
虽然已经在必要的事项中进行了说明,但是前提是对已经存在的Angular应用程序进行Firebase身份验证设置。
如果您要创建新的应用程序,请参考这里的教程。
顺便提一句,大约是这个感觉。
从登录页面通过Google认证进行登录,然后跳转到仪表盘。
在仪表盘中,加载头部组件,并希望在头部组件中显示通过Google认证获取的用户信息中的“显示名称”选项。
安装Firebase库
执行下面的命令。
$ npm install firebase @angular/fire --save
环境.ts
当安装完成后,我们将对以下文件进行修改。
源码路径:环境 > 环境.ts
export const environment = {
production: false,
firebaseConfig: {
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
databaseURL: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
projectId: "xxxxxxxxxxxxx",
storageBucket: "xxxxxxxxxxxxxxx",
messagingSenderId: "xxxxxxxxxxxxxx",
appId: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
};
※这里将复制并粘贴您在应用程序注册时获取的验证信息。
app.module.ts 的中文本地化版本:应用模块.ts
请在此处添加内容。(请不要完全复制粘贴!)
由于尚未创建 AuthService,请不必担心现在出现的错误。
源码 > 应用 > app.module.ts
/* Firebase services */
import { AngularFireModule } from "@angular/fire";
import { AngularFireAuthModule } from "@angular/fire/auth";
import { environment } from '../environments/environment';
/* Auth service */
import { AuthenticationService } from './shared/authentication.service';
@NgModule({
declarations: [...],
imports: [
AngularFireAuthModule,
AngularFireModule.initializeApp(environment.firebaseConfig),
],
providers: [AuthenticationService],
bootstrap: [...],
schemas: [...]
})
export class AppModule { }
“auth.service.ts” can be paraphrased as “认证服务.ts” in Chinese.
首先进行身份验证的源代码。
由于默认情况下文件不存在,因此请执行以下命令来创建文件。
$ ng g s shared/auth
如果能够创建的话,将其替换为以下内容。
如果能够成功登录,则转到仪表盘组件。
源代码 > 应用 > 共享 > auth.service.ts
import { Injectable, NgZone } from '@angular/core';
import { auth } from 'firebase/app';
import { User } from "./user";
import { Router } from "@angular/router";
import { AngularFireAuth } from "@angular/fire/auth";
@Injectable({
providedIn: 'root'
})
export class AuthService {
user: User;
constructor(
public router: Router,
public ngZone: NgZone,
public afAuth: AngularFireAuth,
private angularFireAuth: AngularFireAuth
) {
this.afAuth.authState.subscribe(user => {
this.user = user;
})
}
// Firebase SignInWithPopup
OAuthProvider(provider) {
return this.afAuth.auth.signInWithPopup(provider)
.then((res) => {
this.ngZone.run(() => {
this.router.navigate(['dashboard']);
})
}).catch((error) => {
window.alert(error)
})
}
// Firebase Google Sign-in
SigninWithGoogle() {
return this.OAuthProvider(new auth.GoogleAuthProvider())
.then(res => {
console.log('Successfully logged in!')
}).catch(error => {
console.log(error)
});
}
// Firebase Logout
SignOut() {
return this.afAuth.auth.signOut().then(() => {
this.router.navigate(['login']);
})
}
}
登录组件.ts
这个源在默认情况下也不存在。
我记得应该可以用以下命令创建。
$ ng g c login
我只是在构造函数中添加了AuthService的关联关系。
源代码 > 应用程序 > 登录 > 登录组件.ts
import { Component, OnInit } from '@angular/core';
// Add
import { AuthService } from 'src/app/shared/auth.service';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css']
})
export class LoginComponent implements OnInit {
// 引数を追加
constructor(private authService: AuthService) { }
ngOnInit() { }
}
登录组件.html
HTML很容易。 CSS稍微省略在这里。
重点是在
原文:src > app > login > login.component.html
翻译:源代码 > 应用 > 登录 > 登录组件.html
<form class="sign-up">
<h1 class="sign-up-title">Sign in</h1>
<button (click)="authService.SigninWithGoogle()" class="sign-up-button">
Sign in with Google
</button>
</form>
仪表板组件.ts
我们将创建迁移目标的仪表板组件。
这个命令将一次性创建一整套。
$ ng gc dashboard
TS文件没有从默认设置中进行任何更改。
源代码中的路径是:src > app > dashboard > dashboard.component.ts。
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
constructor() { }
ngOnInit() {
}
}
仪表盘.component.html
这一部分也只是显示头部组件化。
源码 > 应用程序 > 仪表盘 > 仪表盘组件.html
<app-header></app-header>
标题组件.ts
由于我希望将header作为一个组件使用,所以它的层次稍微深了一点。因此,在首次导入时,相对路径会深入一层。我导入AuthService是为了在header中显示登录用户名,并控制登出按钮。
只需添加构造函数的参数。
源代码>应用程序>通用组件>头部>头部组件.ts
import { Component, OnInit } from '@angular/core';
import { AuthService } from '../../shared/auth.service';
@Component({
selector: 'app-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.css']
})
export class HeaderComponent implements OnInit {
// 引数追加
constructor(public authService: AuthService) { }
ngOnInit() {
}
}
头部组件.html
在authService.user.emailVerified中,可以获取认证状态。
如果已经认证,则显示显示名称为{{authService.user.displayName}}。
源代码 > 应用程序 > 公共组件 > 页眉 > 页眉组件.html
<div class="header">
<span class="header_title">Title</span>
<span *ngIf="authService.user.emailVerified" class="header_user_name">Hi! {{authService.user.displayName}}</span>
<button (click)="authService.SignOut()" *ngIf="authService.user.emailVerified" class="logout-button">Logout</button>
</div>
app-routing.module.ts的中文含义是“应用程序路由模块”。
最后,添加路由控制。请根据自己的环境进行修改,这是一个标准的源代码。
源代码 > 应用程序 > app-routing.module.ts
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { DashboardComponent } from './dashboard/dashboard.component';
/*
ここに追記。pathに合わせて、紐付けるコンポーネントを設定します。
*/
const routes: Routes = [
{path: '', redirectTo: '/login', pathMatch: 'full' },
{path: 'login', component: LoginComponent },
{path: 'dashboard', component: DashboardComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(routes),
ReactiveFormsModule,
],
exports: [RouterModule]
})
export class AppRoutingModule { }
那么,发生了什么事情?
我要试试这个登录方式,点击“使用Google账号登录”按钮。
最后
虽然我去过许多地方并做了各种各样的事情,但多亏了大家的帮助,最终还是勉强完成了。
然而,问题还没有完全解决。
-
- Googleアカウントを持っている人なら誰でもいける(でいいのか?)
- 認証はできたものの、そこからのセキュリティも考えなきゃ
尽管如此,认证功能比我想像的要简单得多。
在其他社交媒体账户上也能做到同样的事情。
变得更方便了呢。
请看以下内容:
请用日语仔细教我如何通过电子邮件和密码进行认证(日语)。
以下是Firebase的设置(英文版):
https://www.positronx.io/setup-angularfire2-library-in-angular-7-project/
如果要进行电子邮件和密码的认证,这个链接可能会对你有所帮助:https://www.positronx.io/firebase-authentication-in-angular-8-with-angularfire2/
或许这是最接近的(英语)https://www.positronx.io/angular-8-firebase-google-sign-in-tutorial/