0

I'm having a heck of a time creating drupal services from angular hitting the rest server. I created a rest end point for all my authentication needs, configured in the Service module. When I use POSTMAN plugin to send json data to the endpoints, the register, login, and logout all works correctly. On POSTMAN, I'm able to send the logout endpoint an X-CSRF-Token to force the logout and it's successful. But when I try to recreate this from my Angular app, it discontinues the workflow from login to logout. Here is the following code:

//Called from this.Login success callback, so after you log in,
//this is called to see if I can fetch the same token I logged in with,
//then I'll compare that fetched token with the one created from login
//if they are different, session is not being kept on the server
//if they are the same, drupal is aware that a session is happening
var TokenCompare = function (tokenToCompareFromLogin) {
     return $http({
            method: 'POST',
            url: restAuthConfig.root + '/1.0/user/token',
            headers: {
                'Content-Type': 'application/json'
            }
        }).then(function(response) {
             if (response.data.token == tokenToCompareFromLogin) {
                        $log.log ("We are finally logged in","");
                    } else {
                        $log.log ("We are not logged in", "");
                    }
            $log.log('$membership.Token', response.data.token);
            $log.log('$membership.Login', tokenToCompareFromLogin);
        }, function(error) {
            _isAuthenticated = false;
            $log.log('$membership.IsAuthenticated - Error', error);
            throw error;
    });
}

this.Login = function ($userCreds) {
    $log.log('$membership.Login()', "");
     var _requestObject = {
        "username" : $userCreds.email, 
        "password" : $userCreds.password
    };
     return $http({
                    method: 'POST',
                    url: restAuthConfig.root + '/1.0/user/login',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    data: _requestObject
                }).then(function(response) {
                    TokenCompare(response.data.token)
                    var sessId = response.data.sessid;
                    var sessName = response.data.session_name;
                    $cookies.put(sessName, sessId);
                    $cookies.put("X-CSRF-Token",response.data.token);
                    $cookies.put("CSRF-Token",response.data.token);
                    _isAuthenticated = true;
                    return {
                        data: response.data,
                        status: response.status,
                        raw: response
                    };
                }, function(error) {
                    _isAuthenticated = false;
                    $log.log('$membership.Login - Error', error);
                    throw error;
                });
}

this.Logout = function () {
    _isAuthenticated = false;
        return $http({
                    method: 'POST',
                    url: restAuthConfig.root + '/1.0/user/logout',
                    headers: {
                        'Content-Type': 'application/json',
                        'Accept': 'application/json',
                        'X-CSRF-Token': $cookies.get('X-CSRF-Token')
                    }
                }).then(function(response) {
                    deleteCookie("X-CSRF-Token");
                    return {
                        data: response.data,
                        status: response.status,
                        raw: response
                    };
                }, function(error) {
                    $log.log('$membership.Logout - Error', error);
                    throw error;
                });
}

Then from my controller I have the following lines:

$membership.Login({ email : "[email protected]", password: "1234" });
$membership.Logout();

$membership is the angular service containing the above endpoints.

I was able to register new users, and after calling $membership.Login, I was able to receive a csrf token, and a sessid and sessname, and the response was a 200OK. But when I execute the $membership.Logout(), I get a 406 Not acceptable: User is not logged in. When I look at the TokenCompare function, the token received from api_auth/1.0/token is different than the token received from api_auth/1.0/login endpoint. So I have every reason to believe that a session is started from the login endpoint, is ends as soon as the $http finishes its functionality.

It's a bit difficult to find out that cause, as I mentioned, it works in POSTMAN.

1 Answer 1

1

This took me roughly 14 hours to figure out. But I finally was able to get it done.

I downloaded the CORS module so I can modify the headers and I added the following lines to the configuration

*|http://localhost:3000|GET,POST,DELETE,PUT,OPTIONS,HEAD|Content-Type,Accept,X-CSRF-Token,Cookie|true
#!/*||GET,POST,DELETE,PUT,OPTIONS,HEAD|Content-Type,Accept,X-CSRF-Token,Cookie|true
api/*/*||GET,POST,DELETE,PUT,OPTIONS,HEAD|Content-Type,Accept,X-CSRF-Token,Cookie|true
  • the first line is from any connections coming from the root site.
  • the second line beginnging with #!/* is an appended entry point from the root site, which hits some my own internal services
  • the third line is my api defined from my services module, here is where my authentication happens

The situation that was happening was that I needed to add "withCredentials : true" to the above services. In order to do that, I needed to modify two things

  • Access-Control-Allow-Origin must not contain a wild card, it must have the origin, which is localhost:3000
  • Access-Control-Allow-Credentials must be set to true

Both of those above lines are configured in the CORS module. This is great, because this is configurable from the CORS drupal module UI, rather than editing any php code. After I did that, I added "withCredentials:true" to every single api call I made, and it worked like a charm!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.