Angular 登录后无法获取令牌
该代码应该通过API通过电子邮件和密码登录用户,然后获取访问令牌,但它没有。在本地存储中没有令牌。当我输入错误的密码时,它会在控制台中显示错误,状态为:401,当我输入正确的密码时,它不会显示任何错误,而且在网络选项卡中,对于具有正确密码的请求,状态为200,因此我认为它会登录,但不会获取令牌Angular 登录后无法获取令牌,angular,Angular,该代码应该通过API通过电子邮件和密码登录用户,然后获取访问令牌,但它没有。在本地存储中没有令牌。当我输入错误的密码时,它会在控制台中显示错误,状态为:401,当我输入正确的密码时,它不会显示任何错误,而且在网络选项卡中,对于具有正确密码的请求,状态为200,因此我认为它会登录,但不会获取令牌 import { Component, OnInit } from '@angular/core'; import { FormBuilder, FormGroup, Validators } from
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;
}
});
}
}
从'@angular/core'导入{Injectable};
从'@angular/common/http'导入{HttpClient};
从“rxjs”导入{BehaviorSubject};
@注射的({
providedIn:'根'
})
出口级服务{
checkStatus=新行为主体(false);
isUserLoggedIn=this.checkStatus.asObservable();
readonly loginUrl='https://**************';
构造函数(私有http:HttpClient){}
checkLogin(){
const token=localStorage.getItem('access_token');
如果(令牌){
this.checkStatus.next(true);
}否则{
this.checkStatus.next(false);
}
}
登录用户(用户:任意){
返回this.http.post(this.loginUrl,用户)
.订阅((选中用户:任意)=>{
if(checkUser.access\u令牌){
localStorage.setItem('access\u token',checkUser.access\u token);
setItem('user',JSON.stringify(checkUser.user));
返回true;
}
});
}
}
你的代码看起来不错。天真的问题,您是否检查过您的API是否正确地发送回“checkUser.access_token”并且它不是未定义的
此外,本地存储不是存储身份验证令牌的推荐位置
浏览器本地存储(或会话存储)不安全。任何数据
存储在其中可能容易受到跨站点脚本攻击。如果攻击者
窃取令牌后,他们可以访问并请求您的API
通常在处理SPA时,您会在内存中使用。Cookie也是一个选项,有一些限制和注意事项。如果您使用node.js/express作为后端,我建议使用,因为它非常有助于以安全的方式设置会话访问令牌
关于商店代币,我建议这样读:您的代码看起来不错。天真的问题,您是否检查过您的API是否正确地发送回“checkUser.access_token”并且它不是未定义的 此外,本地存储不是存储身份验证令牌的推荐位置 浏览器本地存储(或会话存储)不安全。任何数据 存储在其中可能容易受到跨站点脚本攻击。如果攻击者 窃取令牌后,他们可以访问并请求您的API 通常在处理SPA时,您会在内存中使用。Cookie也是一个选项,有一些限制和注意事项。如果您使用node.js/express作为后端,我建议使用,因为它非常有助于以安全的方式设置会话访问令牌
关于存储令牌,我建议这样读:在尝试访问令牌之前,您必须等待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']);
}
});
在尝试访问令牌之前,您必须等待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']);
}
});
我用this.loggedIn=val.valueOf()编辑了问题try强制它从
可观察的
返回原语。我使用this.loggedIn=val.valueOf()编辑了问题try
强制它从可观察的
返回原语。因此,也许您应该检查“if(checkUser.success.token)”并设置“localStorage.setItem('access_token',checkUser.success.token);”。我是否遗漏了什么?如果令牌存储在内存中而不是浏览器的本地存储中,那么当重新加载spa网页时会发生什么情况?内存中的数据将被清除。。。因此,用户需要再次登录?是的,这是最简单的安全方法,但肯定不是最有效的方法。这有时是一个可行的解决方案,因为根据您的构建方式,SPA实际上不需要重新加载。在构建更大的应用程序时,您可以使用会话(服务器端会话和令牌ID)或JWT(客户端身份验证),但它们比简单地将其存储在内存中更复杂。因此,也许您应该检查“if(checkUser.success.token)”并设置“localStorage.setItem('access_token',checkUser.success.token);”。我是否遗漏了什么?如果令牌存储在内存中而不是浏览器的本地存储中,那么当重新加载spa网页时会发生什么情况?内存中的数据将被清除。。。因此,用户需要再次登录?是的,这是最简单的安全方法,但肯定不是最有效的方法。这有时是一个可行的解决方案,因为根据您的构建方式,SPA实际上不需要重新加载。在构建更大的应用程序时,您可以使用会话(服务器端会话和令牌ID)或JWT(客户端身份验证),但它们比简单地将其存储在内存中更复杂。