angular - 使用谷歌登录在角度应用程序中不起作用
问题描述
我有 Angular 应用程序,我必须在其中使用 Google 实现登录。
我曾尝试实施此解决方案:https ://developers.google.com/identity/sign-in/web/sign-in?refresh=1 。在这种情况下,我无法获取配置文件数据。
第二种解决方案是编写我自己的 js 代码,我在第一种情况下接收 auth2,但未显示登录弹出窗口。
HTML 模板
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<button class="googleBtn socialBtn" color="accent" mat-stroked-button
(click)="service.submitGoogleLogin()">
<span class="gLogo"></span>
<span>Google</span>
</button>
.TS 文件
export class LoginService implements OnInit {
private auth2: any = undefined;
private readonly gapiUrl: string = 'https://apis.google.com/js/platform.js';
dialogRegulation;
fbToken;
loginData;
@Input()
element: ElementRef;
constructor(
private http: HttpClient,
) {
this.initGoogleLogin().subscribe();
}
initGoogleLogin(): Observable<boolean> {
return new Observable((observer: Observer<boolean>) => {
const meta = document.createElement('meta');
meta.name = 'google-signin-client_id';
meta.content = env.google.clientId;
document.getElementsByTagName('head')[0].appendChild(meta);
const node = document.createElement('script');
node.src = this.gapiUrl;
node.type = 'text/javascript';
document.getElementsByTagName('body')[0].appendChild(node);
node.onload = () => {
observer.next(true);
observer.complete();
};
});
}
submitGoogleLogin() {
gapi.load('auth2', () => {
gapi.auth2
.getAuthInstance({
client_id: env.google.clientId,
cookiepolicy: 'single_host_origin',
scope: env.google.scope.join(' '),
})
.then((auth: any) => {
this.auth2 = auth;
})
.catch((err: any) => console.log(err));
});
}
onSignIn(googleUser) {
const profile = googleUser.getBasicProfile();
console.log('Token || ' + googleUser.getAuthResponse().id_token);
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
}
setGoogleLoginUser() {
console.log('Welcome! Fetching your information.... ');
// Add REST loginGoogle
//this.authService.setIsLoggedInValue();
//this.element.nativeElement.firstChild;
this.auth2.attachClickHandler(
this.element,
{},
googleUser => {
const profile = googleUser.getBasicProfile();
console.log('Token || ' + googleUser.getAuthResponse().id_token);
console.log('ID: ' + profile.getId());
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail());
},
function(error) {
console.log(JSON.stringify(error, undefined, 2));
}
);
}
我的目标是获取我必须发送到后端才能获取令牌的 id。
解决方案
使用 Angular 登录 Google 并不是那么容易。如果你不小心,你会遇到区域问题或时间问题
我用这个版本。
import { Injectable, NgZone } from '@angular/core';
import { BehaviorSubject, Observable, merge, of } from 'rxjs';
import { filter, catchError, switchMap, tap } from 'rxjs/operators';
import { ILoginProvider } from '../entities/ILoginProvider';
import { SocialUser } from '../entities/SocialUser';
import { AuthConfig } from '../config';
export declare let gapi: any;
@Injectable()
export class GoogleLoginProvider implements ILoginProvider {
constructor(private zone: NgZone) {
this.loadGoogleScript().then(() => {
console.log((window as any).Zone.current.name);
return this.zone.run(() => this.init$.next(true));
});
}
public authenticated: boolean;
private readonly url = 'https://apis.google.com/js/platform.js';
private init$ = new BehaviorSubject<boolean>(false);
private googleAuth: any;
public acquireToken(): Observable<string> {
return new Observable((subscriber) => {
this.init$.pipe(filter((x) => x)).subscribe(() => {
const isSignedIn = this.googleAuth.isSignedIn.get();
const token = isSignedIn ? this.googleAuth.currentUser.get().getAuthResponse(true).id_token : null;
this.authenticated = !(!token);
subscriber.next(token);
});
});
}
public signIn(): Observable<SocialUser> {
const z1$ = this.init$.pipe(
filter(x => x && !this.googleAuth.isSignedIn.get()),
switchMap(() => {
return new Observable(subscriber => {
this.googleAuth.signIn().then(() => this.zone.run(() => {
this.authenticated = true;
subscriber.next();
}));
});
}),
);
const z2$ = this.init$.pipe(filter(x => x && this.googleAuth.isSignedIn.get()), tap(_ => this.authenticated = true));
return merge(z1$, z2$).pipe(catchError(_ => of(null))); // catch error when closing login screen
}
public signOut(): Observable<any> {
return new Observable((subscriber) => {
this.googleAuth.signOut().then((err: any) => {
this.authenticated = false;
subscriber.next(err);
});
});
}
public getSocialUser(): SocialUser {
let profile: any;
let authResponseObj: any;
profile = this.googleAuth.currentUser.get().getBasicProfile();
authResponseObj = this.googleAuth.currentUser.get().getAuthResponse(true);
if (!profile || !authResponseObj) {
return null;
}
const user: SocialUser = {
id: profile.getId(),
name: profile.getName(),
email: profile.getEmail(),
photoUrl: profile.getImageUrl(),
} as SocialUser;
return user;
}
private loadGoogleScript() {
return new Promise((resolve) => {
this.loadScript(this.url, () => this.googleLoad().then(() => resolve(true)));
});
}
private googleLoad() {
return new Promise((resolve) => gapi.load('auth2', () => this.googleInit().then(() => resolve(true))));
}
private googleInit() {
const config = AuthConfig.GOOGLE.config;
return new Promise((resolve) => {
this.googleAuth = gapi.auth2.init({ client_id: config, scope: 'email' });
this.googleAuth.then(() => resolve(true));
});
}
private loadScript(url: string, onload: any) {
const signInJS = document.createElement('script');
signInJS.async = true;
signInJS.src = url;
signInJS.onload = onload;
document.head.appendChild(signInJS);
}
}
推荐阅读
- c - 为堆分配的对象抛弃“const”是否合法/安全?
- c - 为什么 printf(创建单位矩阵)不打印输出?
- cmd - 将具有所有依赖项的 Nuget 包下载到文件夹的命令
- swift - 更新我在 iOS 项目中手动添加的库的问题
- haskell - Haskell 状态单子在偶数和奇数函数调用上的不同行为
- c - 完成下面的源代码以构建一个按字典顺序打印出第一个字符串的程序
- c++ - 在 C++ 中打印当前时间并更新每一帧并获取输入
- chmod - su:无法在 rhel 7 上设置组操作不允许
- javascript - 在fabric.js中将文本锁定在前面(不是每次都放在前面)
- node.js - Azure NodeJS WebApp 上的静态服务 Socket.IO