该代码应该通过API通过电子邮件和密码登录用户,然后获取访问令牌,但事实并非如此。在本地存储中没有令牌。当我输入错误的密码时,它在控制台中显示错误,状态为401;当我输入正确的密码时,它没有显示任何错误,并且在网络选项卡中,使用正确密码的请求的状态也为200,因此我认为它的日志记录是进入但未获取令牌。
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ApiService } from '../api.service';
import { Router } from '@angular/router';
@Component({
selector: 'app-login1',
templateUrl: './login1.component.html',
styleUrls: ['./login1.component.css']
})
export class Login1Component implements OnInit {
loggedIn = false;
loginForm: FormGroup;
constructor(private api: ApiService, private route: Router, private formBuilder: FormBuilder) { }
ngOnInit() {
this.loginForm = this.formBuilder.group({
email: ['', Validators.required],
password: ['', Validators.required]
})
}
onSubmit() {
const user = {
email: this.loginForm.controls.email.value,
password: this.loginForm.controls.password.value
};
this.api.loginUser(user);
this.api.isUserLoggedIn.subscribe( (val) => {
this.loggedIn = val;
this.route.navigate(['/dashboard']);
});
}
}
服务
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ApiService {
checkStatus = new BehaviorSubject<boolean>(false);
isUserLoggedIn = this.checkStatus.asObservable();
readonly loginUrl= 'https://*************';
constructor(private http: HttpClient) { }
checkLogin() {
const token = localStorage.getItem('access_token');
if(token) {
this.checkStatus.next(true);
} else {
this.checkStatus.next(false);
}
}
loginUser(user: any) {
return this.http.post(this.loginUrl, user)
.subscribe((checkUser: any) => {
if(checkUser.access_token) {
localStorage.setItem('access_token', checkUser.access_token);
localStorage.setItem('user', JSON.stringify(checkUser.user));
return true;
}
});
}
}
答案 0 :(得分:2)
您的代码看起来不错。天真的问题,您是否检查过API是否正确发送回“ checkUser.access_token”并且它不是未定义的?
此外,不建议在本地存储身份验证令牌。
浏览器本地存储(或会话存储)不安全。任何数据 存储在那里可能容易受到跨站点脚本的攻击。如果攻击者 窃取令牌,他们就可以访问您的API并向其发出请求。
通常在处理SPA时会在内存中使用。 Cookies也是一个有一些限制和注意点的选项。如果您使用node.js / express作为后端,我建议您使用https://github.com/expressjs/session,因为它以安全的方式设置会话访问令牌非常有帮助。
关于商店令牌,我建议阅读:https://auth0.com/docs/security/store-tokens
答案 1 :(得分:0)
您必须先等待loginUser才能尝试访问令牌
this.api.loginUser(user).subscribe(() => {
this.api.isUserLoggedIn.subscribe( (val) => {
this.loggedIn = val;
this.route.navigate(['/dashboard']);
});
});
说实话,我什至看不到订阅isUserLoggedIn的意义。相反,您可以使用loginUser方法中返回的值
this.api.loginUser(user).subscribe((val) => {
this.loggedIn = val;
if (val) {
this.route.navigate(['/dashboard']);
}
});