[英]Angular2 Http Call not firing
内容:
在完成了几篇教程之后,我将测试Angular2和JWT的身份验证。 我带有一个组件和一个服务:
app.component.ts
user.service.ts
应用程序组件(和模板)包含对可观察对象的订阅,该订阅显示了用户的登录状态。 “可观察”项保留在用户服务中,并且在用户登录和注销时进行更改(精细)。
身份验证令牌在“ localStorage”中写为“ auth_token”。 它包含一个有效性值(时间),该值应迫使用户在一段时间后再次登录。
我想做的是在应用程序初始化中检查令牌的有效性。 首先,我尝试从user.service构造器执行此操作,然后(失败),尝试从app.component中的ngOnInit执行操作,然后(再次失败),我尝试在事件调用时执行操作(单击a按钮),但再次失败!
一些缩短的代码:
//app.component.html
//...
<a md-button class="app-icon-button" aria-label="checklogin" (click)="checkLogin()">
<md-icon svgIcon="check"></md-icon>
</a>
//...
//app.component.ts
//...
checkLogin(){
console.log('CHECK LOGIN FUNCTION');
let token = localStorage.getItem('auth_token');
if(token){
console.log('TOKEN FOUND');
this.userService.checkToken(token);
}else{
console.log('NO TOKEN FOUND');
}
}
//...
//user.service.ts
//...
checkToken(token){
console.log('CHECK TOKEN FUNCTION');
console.log('TOKEN : '+token);
let headers = new Headers();
headers.append('Content-Type','application/json');
return this.http
.post(
'/url/script.php',
JSON.stringify(token),
{ headers }
)
.map(res => res.json())
.map((res) => {
console.log('SCRIPT RESULT : ');
if(res.valid){
console.log('TOKEN IS VALID');
return true;
}else{
console.log('TOKEN NOT VALID');
return false;
}
});
}
//...
我确实跳过了可观察的部分和订阅。
问题:
问题实际上是该应用程序从不调用脚本!
当我确实点击“ checkLogin”按钮时(如果存在令牌),
console shows 'CHECK LOGIN FUNCTION',
console shows 'TOKEN FOUND',
console shows 'CHECK TOKEN FUNCTION',
console shows 'TOKEN : '****************************** (token),
但是它永远不会显示“ SCRIPT RESULT”,并且在使用Firebug检查http调用是否完成时,script.php没有调用。 看起来this.http部分只是被忽略了...
感谢您的阅读/帮助
仅当您有一个subscriber
,使用Observables
Ajax调用才有效。
因此,您需要subscribe
该Observable
。 这是Angular 2
功能。 当您不订阅Observable
,它将永远不会进行该调用。
同样,您也不需要从订阅服务器返回任何内容,因为您实际上无法返回任何内容。
this.userService.checkToken(token).subscribe((res) => {
console.log('SCRIPT RESULT : ');
if(res.valid) {
console.log('TOKEN IS VALID');
} else {
console.log('TOKEN NOT VALID');
}
});
checkToken(token){
console.log('CHECK TOKEN FUNCTION');
console.log('TOKEN : '+token);
let headers = new Headers();
headers.append('Content-Type','application/json');
return this.http
.post(
'/url/script.php',
JSON.stringify(token),
{ headers }
)
.map(res => res.json());
}
当订阅仅在使用者使用.subscribe
方法订阅输出结果时使用时,服务才能开始工作。
您需要: this.userService.checkToken(token).subscribe()
您的checkToken()
方法返回一个需要subsrcibe
的Observable
。 可观察对象除非已订阅,否则将永远不会执行。
checkLogin(){
console.log('CHECK LOGIN FUNCTION');
let token = localStorage.getItem('auth_token');
if(token){
console.log('TOKEN FOUND');
this.userService.checkToken(token).subscribe(result => {
console.log(result);
}),
error => {
console.log(error);
});
} else {
console.log('NO TOKEN FOUND');
}
}
您是否尝试过使用Postman
并尝试调用所需的函数?
另外,如果angular2-jwt
可以为您做到这一点,为什么还要验证令牌?
您可以这样做:
使用npm
安装angular2-jwt
。
包含在app.module.ts
:
import { AUTH_PROVIDERS } from 'angular2-jwt';
添加到提供者:
providers: [
AUTH_PROVIDERS,
],
例如auth.service.ts
看起来像这样:
import { Injectable, Inject } from '@angular/core';
import { Http, Response, Headers, RequestOptions, RequestMethod } from '@angular/http';
import { Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../../app.config';
import { RegisterViewModel } from '../../model/viewModel/registerViewModel';
import { LoginViewModel } from '../../model/viewModel/loginViewModel';
import { tokenNotExpired, AuthHttp } from 'angular2-jwt';
@Injectable()
export class AuthService {
private actionUrl: string;
constructor(private _http: Http, private _config: Configuration, private _router: Router, private _authHttp: AuthHttp){
this.actionUrl = _config.apiUrl;
}
register(user: RegisterViewModel){
let headers = new Headers({ 'Content-Type': 'application/json' });
//Admin in this system can only register users. that is why auth
return this._authHttp.post(this.actionUrl + '/Account/Register', JSON.stringify(user), { headers : headers })
.do(response => {
console.log(response.toString());
});
}
login(user: LoginViewModel) {
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
return this._http.post('http://localhost:56181/api/token', "username=" + user.userName + "&password=" + user.password + "&userId=" + user.userId, { headers : headers })
.do(response => {
if(response){
let authResult = response.json();
this.setUser(authResult);
this._router.navigate(['']);
}
});
}
public isAuthenticated(): boolean {
//angular2-jwt has this function to check if token is valid
return tokenNotExpired();
}
private setUser(authResult: any): void {
localStorage.setItem('id_token', authResult.id_token);
}
public logout(): void {
localStorage.removeItem('id_token');
this._router.navigate(['']);
}
}
还要记住, angular2-jwt
在localstorage
id_token
令牌的默认名称为id_token
,否则您将不得不使用angular2-jwt
帮助类来指定其他令牌名称。
您只需执行以下操作即可检查其是否正常工作:
在app.component.ts
:
export class AppComponent {
constructor(private _auth: AuthService){
}
}
并在app.component.html
:
<li>
<a class="nav-link" [routerLink]="['/login']" *ngIf="!_auth.isAuthenticated()">Login</a>
</li>
<li>
<a class="nav-link" (click)="_auth.logout()" *ngIf="_auth.isAuthenticated()">Log Out</a>
</li>
您也可以在以下位置阅读有关它的一些文档:
https://auth0.com/blog/introducing-angular2-jwt-a-library-for-angular2-authentication/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.