jaredt
jaredt

Reputation: 41

Angular2 and Drupal 7 Service API Authentication

I am using the Drupal 7 Services API (v7.x-3.17) to connect with an Angular2 front-end.

I am having trouble getting the authentication working properly. When I login I receive all of the correct data back (session_name, sessid, token, etc…). However, when I make any other subsequent calls (i.e. system/connect) it returns a different “sessid” and tells me that I’m an “anonymous user”.

It just doesn’t recognize that I just logged in. Here are the steps I am taking:

  1. Login via the “user/login” call.
  2. API returns “sessid”, “session_name”, “token”, and “user” object with all the correct user information.
  3. Store the X-CSRF-TOKEN for subsequent API calls.
  4. Add “X-CSRF-TOKEN” to the header and call API to get user information via “system/connect” call.
  5. API returns a new/different “sessid”, the same “session_name”, and a “user” block for an “anonymous user”.

For the life of me, I can’t figure out why it is returning an anonymous user. Can anyone help me to figure this out?

Here is my user/login function:

////////////////////////////////////////////////////
//  LOGIN API CALL
// make call to login with 'user/login' api call
////////////////////////////////////////////////////

login(data): Observable<User> {

    // set variables
    let url = this.postUrl + 'user/login';
    let headers = new Headers({'Content-Type': 'application/json'}); 
    let options = new RequestOptions({ headers: headers});

    // make the call
    return this.http.post(url, data, options) 
       .map((res:Response) => this.loginData(res)) 
       .catch((error:any) => this.handleError(error)); 

}

private loginData(res: Response) {
    let body = res.json();
    Cookie.set('X-CSRF-TOKEN', body.token);
    return body!=null?body:[];
}

Here is my user/connect function:

////////////////////////////////////////////////////
// GET USER DATA OR "CONNECT" API CALL
// get user data with 'system/connect' api call
////////////////////////////////////////////////////

getUser(): Observable<any> {

    // Retrieve the token
    let token = Cookie.get('X-CSRF-TOKEN');

    // Prepare API call
    let url = this.postUrl + 'system/connect';
    let body = { username: 'test', password: 'test' };
    let headers = new Headers('X-CSRF-TOKEN', token);
    headers.append('Content-Type', 'application/json');

    let options = new RequestOptions({ headers: headers, withCredentials: true });

    return this.http.post(url, body, options) 
       .map((res:Response) => this.extractData(res)) 
       .catch((error:any) => this.handleError(error)); 

}

Upvotes: 2

Views: 742

Answers (1)

jaredt
jaredt

Reputation: 41

so.... I'm gonna answer my own question :)

This was, in fact, a CORS issue. The login was working and responding with a "set-cookie" response with my session_name and sessid. But, the browser was not setting the cookie and, therefore, all subsequent calls didn't know that I was an authenticated user.

The solution? Add "withCredentials: true" to the header of my Login API call. Like so:

let options = new RequestOptions({ headers: headers, withCredentials: true});

I hope this helps anyone else who has this issue.

Upvotes: 2

Related Questions