简体   繁体   English

Angular2 Http Call未触发

[英]Angular2 Http Call not firing

Context : 内容:

Following several tutorials, I am testing authentication with Angular2 and JWT. 在完成了几篇教程之后,我将测试Angular2和JWT的身份验证。 I come with a component and a service : 我带有一个组件和一个服务:

app.component.ts
user.service.ts

App component (and template) contains the subscription to an observable that shows the user logged in status. 应用程序组件(和模板)包含对可观察对象的订阅,该订阅显示了用户的登录状态。 The Observable item is kept in the user service, and changes (fine) when user logs in and out. “可观察”项保留在用户服务中,并且在用户登录和注销时进行更改(精细)。

The authentication token is written in "localStorage" as "auth_token". 身份验证令牌在“ localStorage”中写为“ auth_token”。 It contains a validity value (time) that should force the user to login again after a time. 它包含一个有效性值(时间),该值应迫使用户在一段时间后再次登录。

What I'd like to do is to CHECK the token validity on app init. 我想做的是在应用程序初始化中检查令牌的有效性。 First, I tried to do it from the user.service CONSTRUCTOR, then (fail), I tried to do it from ngOnInit in the app.component, then (fail again), I tried to do it on event call (click on a button) from the app component, but fails again! 首先,我尝试从user.service构造器执行此操作,然后(失败),尝试从app.component中的ngOnInit执行操作,然后(再次失败),我尝试在事件调用时执行操作(单击a按钮),但再次失败!

Some shortened code : 一些缩短的代码:

//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;
                }
            });
    }
//...

I did skip the observable part, and subscription. 我确实跳过了可观察的部分和订阅。

Problem : 问题:

The problem actually is that the app NEVER CALLS the script! 问题实际上是该应用程序从不调用脚本!

When I do click on the "checkLogin" button (when token exists), 当我确实点击“ checkLogin”按钮时(如果存在令牌),

console shows 'CHECK LOGIN FUNCTION',
console shows 'TOKEN FOUND',
console shows 'CHECK TOKEN FUNCTION',
console shows 'TOKEN : '****************************** (token),

But it never shows 'SCRIPT RESULT', and when using firebug to check if the http call is done, there is NO CALL to the script.php. 但是它永远不会显示“ SCRIPT RESULT”,并且在使用Firebug检查http调用是否完成时,script.php没有调用。 Looks like the this.http part is just ignored... 看起来this.http部分只是被忽略了...

Thanks for reading/help 感谢您的阅读/帮助

Ajax call's which use Observables will work only if you have an subscriber . 仅当您有一个subscriber ,使用Observables Ajax调用才有效。

So you need to subscribe to that Observable . 因此,您需要subscribeObservable It is an Angular 2 feature. 这是Angular 2功能。 When you don't subscribe the Observable , it will never make that call. 当您不订阅Observable ,它将永远不会进行该调用。

And also you don't need to return anything from the subscriber, because you actually can't return anything. 同样,您也不需要从订阅服务器返回任何内容,因为您实际上无法返回任何内容。

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());           
}

Service starts working when subscription used only when consumer subscribe to output result, using .subscribe method. 当订阅仅在使用者使用.subscribe方法订阅输出结果时使用时,服务才能开始工作。

You need: this.userService.checkToken(token).subscribe() 您需要: this.userService.checkToken(token).subscribe()

Your checkToken() method is returning an Observable that you need to subsrcibe to. 您的checkToken()方法返回一个需要subsrcibeObservable An observable will never to execute unless it's subscribed to. 可观察对象除非已订阅,否则将永远不会执行。

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');
        }
    }

Have You tried using Postman and try to call function you need? 您是否尝试过使用Postman并尝试调用所需的函数?

Also, why do You need to validate a token if angular2-jwt can do this for You? 另外,如果angular2-jwt可以为您做到这一点,为什么还要验证令牌?

You can do just like this: 您可以这样做:

install angular2-jwt with npm . 使用npm安装angular2-jwt

Include in app.module.ts : 包含在app.module.ts

import { AUTH_PROVIDERS } from 'angular2-jwt';

add to providers: 添加到提供者:

providers: [
    AUTH_PROVIDERS,
],

and for example auth.service.ts looks like this: 例如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(['']);
}

} }

also remember that angular2-jwt has default name for token in localstorage as id_token or else you will have to use angular2-jwt help class to specify other token name. 还要记住, angular2-jwtlocalstorage id_token令牌的默认名称为id_token ,否则您将不得不使用angular2-jwt帮助类来指定其他令牌名称。

You can check if it is working by simply doing this: 您只需执行以下操作即可检查其是否正常工作:

in app.component.ts : app.component.ts

export class AppComponent { 
constructor(private _auth: AuthService){
}
}

and in app.component.html : 并在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>

also You can read a little bit documentation about it in: 您也可以在以下位置阅读有关它的一些文档:

https://auth0.com/blog/introducing-angular2-jwt-a-library-for-angular2-authentication/ https://auth0.com/blog/introducing-angular2-jwt-a-library-for-angular2-authentication/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM