Angular2 login service jwt token

2019-08-28 13:43发布

I try to implement the jwt token with angular2 front-end. When I try receive the token with post method using Postman I receive authorization token but doing so in Angular returns null response object. Here's snippet code of Angular service I use.

    return this.http.post(this.authUrl, { username: username, password: password })
                .map((response: Response) => {
                    console.log(username + ' ' + password);
                    // login successful if there's a jwt token in the response
                    let token = response.json() && response.json().token;
                    console.log(token);
                    if (token) {
                        // set token property
                        this.token = token;

                        // store username and jwt token in local storage to keep user logged in between page refreshes
                        localStorage.setItem('currentUser', JSON.stringify({ username: username, token: token }));

                        // return true to indicate successful login
                        return true;
                    } else {
                        // return false to indicate failed login
                        return false;
                    }
                });

The thing is that when I try to log the token is null same with response. For the back-end portion of code I followed this implementation of jwt token.

The only clue I have is that trying to invoke post method like that

this.http.post<any>(this.authUrl, { username: username, password: password }).subscribe();

I receive Subscriber object. Doing so with toPromise() instead of subscribe() I got ZoneAwarePromise but I cannot locate token in both cases.

3条回答
混吃等死
2楼-- · 2019-08-28 14:08

Try something like this. You need to retrieve the token from the authorization header, not from the body.

From the curl sample in the link you provided, you must call your service with type application/x-www-form-urlencoded

It might not work straight away (not sure what content type your backend returns). If it's not json you might need to modify it. But that should be enough to get you going.

    login(username: string, password: string): Observable<boolean>
    {
        const body = new HttpParams()
            .set('username', username)
            .set('password', password);

        return this.http.post(this.authUrl, body.toString(),
            {
                observe: 'response',//for 'special' headers in response
                headers: new HttpHeaders()
                    .set('Content-Type', 'application/x-www-form-urlencoded')
            })

            .map((response: any) => {

                let authHeader = response.headers.get('Authorization');
                //handle header here
                return true;

            });
    }

Edit:

If your back end is not on the same domain as the front, you need to 'expose' these headers, using the Access-Control-Expose-Headers header in your backend So your server response should have that header

Access-Control-Expose-Headers: Authorization

(see https://stackoverflow.com/a/48306230/1160794)

查看更多
smile是对你的礼貌
3楼-- · 2019-08-28 14:11

When you are sending headers from angular, Api needs to allow origins of requests. Add this code in Spring Boot controller above the class like below. After that Api will be allowed to get headers.

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
public class AuthenticationController {
    //services...
}
查看更多
我命由我不由天
4楼-- · 2019-08-28 14:30

I found the solution. What I needed to do is simply add Access-Control-Expose-Headers with string name of my header. Adding only Access-Control-Allow-Headers didn't work. Then on client side I could extract the header with the name of my header or any more header allowed by the back-end.

查看更多
登录 后发表回答