我在Angular项目中使用Firebase实时数据库。我有一个简单的卡片组数据库,我使用firebase auth API创建了一个简单的身份验证逻辑,我设置了如下数据库访问规则:
{
"rules": {
".read": "auth != null",
".write": "auth != null"
}
}
这是我在2个文件(服务和组件)中的身份验证逻辑,这是服务:
import { tap } from "rxjs/operators";
import { Injectable } from "@angular/core";
import { HttpClient, HttpErrorResponse } from "@angular/common/http";
import { catchError } from "rxjs/operators";
import { throwError, Subject } from "rxjs";
import { User } from "./user.model";
export interface AuthResponseData {
idToken: string;
email: string;
refreshToken: string;
expiresIn: string;
localId: string;
registered?: boolean;
}
@Injectable({ providedIn: "root" })
export class AuthService {
user = new Subject<User>();
constructor(private http: HttpClient) {}
signup(email: string, password: string) {
return this.http
.post<AuthResponseData>(
"https://identitytoolkit.googleapis.com/v1/accounts:signUp?key=AIzaSyCXKvAogUtEvySFdP1rIiJgTriL0QFeUP4",
{
email: email,
password: password,
returnSecureToken: true,
}
)
.pipe(
catchError(this.handleError),
tap((resData) => {
this.handleAuthentication(
resData.email,
resData.localId,
resData.idToken,
+resData.expiresIn
);
})
);
}
login(email: string, password: string) {
return this.http
.post<AuthResponseData>(
"https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=AIzaSyCXKvAogUtEvySFdP1rIiJgTriL0QFeUP4",
{
email: email,
password: password,
returnSecureToken: true,
}
)
.pipe(catchError(this.handleError), tap((resData) => {
this.handleAuthentication(
resData.email,
resData.localId,
resData.idToken,
+resData.expiresIn
);
}));
}
private handleAuthentication(
email: string,
userId: string,
token: string,
expiresIn: number
) {
const expirationDate = new Date(new Date().getTime() + expiresIn * 1000);
const user = new User(email, userId, token, expirationDate);
this.user.next(user);
}
private handleError(errorRes: HttpErrorResponse) {
let errorMessage = "An error occurred";
if (!errorRes.error || !errorRes.error.error) {
return throwError(errorMessage);
}
switch (errorRes.error.error.message) {
case "EMAIL_EXISTS":
errorMessage = "This email already exists!";
break;
case "EMAIL_NOT_FOUND":
errorMessage = "This email does not exist!";
break;
case "INVALID_PASSWORD":
errorMessage = "This password is wrong!";
break;
}
return throwError(errorMessage);
}
}
这是组件:
import { Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService, AuthResponseData } from './auth.service';
import { NgForm } from '@angular/forms';
import { Component } from '@angular/core';
@Component({
selector: 'app-auth',
templateUrl: './auth.component.html',
})
export class AuthComponent {
isLoginMode = true;
isLoading = false;
error: string = null;
constructor(private authService: AuthService, private router: Router) {}
onSwitchMode() {
this.isLoginMode = !this.isLoginMode;
}
onSubmit(form: NgForm) {
if (!form.valid) {
return;
}
console.log(form.value);
const email = form.value.email;
const password = form.value.password;
let authObs: Observable<AuthResponseData>;
this.isLoading = true;
if (this.isLoginMode) {
authObs = this.authService.login(email, password);
} else {
authObs = this.authService.signup(email, password);
}
authObs.subscribe(
resData => {
console.log(resData);
this.isLoading = false;
this.router.navigate(['/decks']);
},
errorMessage => {
console.log(errorMessage);
this.error = errorMessage;
this.isLoading = false;
}
);
form.reset();
}
}
注册工作正常,并且我在Firebase中看到注册用户,但是当我尝试登录时得到以下响应:
{kind: "identitytoolkit#VerifyPasswordResponse", localId: "502dZv8GZzNCpPx2p1XM5DKmpv62", email: "test@test.com", displayName: "", idToken: "eyJhbGciOiJSUz...iIsImtpZCI6ImY1YzlhZWJlMjM0ZGE2MD…gQ0X6EUKKmv0fB8fzXBRQQMrNY0cgHj0hEWRn1PvtLGxGPx-A", …}
displayName: ""
email: "test@test.com"
expiresIn: "3600"
idToken: "eyJhbGciOiJSUzI1NiIsImtpZCI6ImY1YzlhZWJlMjM0ZGE2MDE2YmQ3Yjk0OTE2OGI4Y2Q1YjRlYzllZWIiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL3NlY3VyZXRva2VuLmdvb2dsZS5jb20vYW5nLWNhcmRzIiwiYXVkIjoiYW5nLWNhcmRzIiwiYXV0aF90aW1lIjoxNTkwMDYzNTQ5LCJ1c2VyX2lkIjoiNTAyZFEdaek5DcFB4MnAxWE01REttcHY2MiIsInN1YiI6IjUwMmRadjhHWnpOQ3BQeDJwMVhNNURLbXB2NjIiLCJpYXQiOjE1OTAwNDksImV4cCI6MTU5MDA2NzE0OSwiZW1haWwiOiJ0ZXN0QHRlc3QuY29tIiwiZW1haWxfdmVyaWZpZWQiOmZhbHNlLCJmaXJlYmFzZSI6eyJpGl0aWVzIjp7ImVtYWlsIjpbInRlc3RAdGVzdC5jb20iXX0sInNpZ25faW5fcHJvdmlkZXIiOiJwYXNzd29yZCJ9fQ.DoP2FeIlP4Q4aIjWbBs_Z8Jo--ptuvEoj7Uy1qbUNDUr1VFkUlq-iddAnEu3knIGc8QpexoUPgBwvMrXljJDgExFm0AwLVLo23nn6OAAXOXAPrrNaFcRQgfuIu0rjtOzH6W-_Ne4e2THEd1NqWkrfsixk6WwAsYMAVVMk...OEERbCwfMZV5a7Y7RoNsJydMFGFghOBtZI0-BWyqgZJr_HyrAZxzdpCPzAhcN6WYfk-EK9vRWXM4kjWulpAyvJcoD_XNR_wbKkog9FXRX3pONELvBPM9oMnMaOZdu6udgQ0X6EUKKmv0fB8fzXBRQQMrNY0cgHj0hEWRn1PvtLGxGPx-A"
kind: "identitytoolkit#VerifyPasswordResponse"
localId: "502dZv8GZz...NCpp1XM5DKmpv62"
refreshToken: "AE0u-NcG9G0W7y75-9s9iFXGs..aODsE04Kc4lfbQR2stlB_E3KsJkS0XGB-lDQ-edFBDOFAeozebNlPCw7wGvGxZK2vXdqvHj8LnNjFAVzS9Zf5FW32irgXHn9y1Cdsb9_ww0piwqgxcPaWLo7UhiWGC0YL8jKtFSmfbLctez9RI-C4OVB0m3WC9W4USFlWxBToEhY3"
registered: true
和此错误:
HttpErrorResponse {headers: HttpHeaders, status: 401, statusText: "Unauthorized", url: "https://ang-cards.firebaseio.com/decks.json", ok: false, …}
error: {error: "Permission denied"}
headers: HttpHeaders
lazyInit: () => {…}
lazyUpdate: null
normalizedNames: Map(0) {}
__proto__: Object
message: "Http failure response for https://ang-cards.firebaseio.com/decks.json: 401 Unauthorized"
name: "HttpErrorResponse"
ok: false
status: 401
statusText: "Unauthorized"
url: "https://ang-cards.firebaseio.com/decks.json"
为什么我会收到“权限被拒绝”的信息? 我在做什么错了?
这是在其中导航的卡片组列表组件的初始化
ngOnInit() {
this.decks = this.deckService.getDecks();
this.dataStorageService.fetchDecks();
this.deckService.decksChanged.subscribe((decks: Deck[]) => {
this.decks = decks;
this.dataStorageService.storeDecks();
});
}
答案 0 :(得分:0)
我刚刚意识到我忘了攻击获取请求的令牌,我想这是问题所在