angularjsnode.jsjwtsatellizeroauth-2.0

OAuth2 with Satellizer and a generic OAuth2 provider


I'm having much trouble getting OAuth2 to work with a generic OAuth2 provider. Here's the situation.

A service provides an OAuth2 authentication method to where I want to authorize with. I've created an AngularJS app that has the following configuration for satellizer:

authProvider.baseUrl = 'http://localhost:3030/user/authorize';
    $authProvider.oauth2({
        name: 'customname',
        url: '/token',
        clientId: 'someapp',
        requiredUrlParams: ['scope'],
        scope: ['profile'],
        authorizationEndpoint: 'http://location.to.oathserver',
        redirectUri: 'http://localhost:3000'
    });

The baseUrl points to my node server that should handle the middleware part.

I've also the following code that triggers the authentication part.

$scope.authenticate = function(provider) {
    $auth.authenticate(provider)
        .then(function(response) {
            console.log(response);
        })
        .catch(function() {
            //something went wrong
        });
}

So far this all seems to work great and looks very similar to what is documented by Satellizer! Now once I start the angular app and start the authentication I see requests coming by that target my Node service.

Next I've my node.js service that hooks to the 'user/authorize/token' URL. Here's the code:

router.options('/authorize/token', function(req, res, next) {
    //var token = req.header('Authorization').split(' ')[1];
    res.end();
});

and:

router.post('/authorize/token', function(req, res, next) {
    var authCode = req.param('code');
    var cliendId = req.param('clientId');
    var payload = jwt.decode(authCode, 'mySecret');
});

Here's where it all seems to go wrong. First I seem to get an OPTIONS request. I've not really an idea what to do with it as I can't seem to find anything in the documentation about an OPTIONS request. I thought it would might contain the 'Authorization' header but that doesn't seem the case so I close the connection with a res.end();

I also inspected the request in Chrome but I can't seem to find a header that has this exact name.

Next I get a POST request. This does seem to contain some things, hooray! I get the following object:

{
    code: "ZFFeat9pWfHzw4rGmjFYwucPRMFnBOkd2odEObvo",
    cliendId: "someapp",
    redirectiUri: "http://localhost:3000"
}

This looks to me like the authorization code that I should have to decode. That's what you see me trying as well in the code above. Unfortunately this seems to throw me an error

Error: Not enough or too many segments

This tells me I'm doing probably something wrong, and I got stuck.

I do have some PHP code that seems to work for someone else but I don't fully understand and can't really relate the code to my code since PHP is not my speciality and node.js/JavaScript not his. So here goes the PHP code:

handle_cors(); // Handle CORS for cross domain requests

// Get JSON data
$input = json_decode(file_get_contents("php://input"), true);

// Create Provider
$provider = new SomeApp\OAuth2\Client\Provider\SomeApp([
    'clientId'          => 'someapp',
    'clientSecret'      => 'mySecret',
    'redirectUri'       => $input['redirectUri'],
]);

// Optional: Now you have a token you can look up a users profile data
try {

    // Try to get an access token (using the authorization code grant)
    $token = $provider->getAccessToken('authorization_code', [
        'code' => $input['code']
    ]);

    // We got an access token, let's now get the user's details
    $user = $provider->getResourceOwner($token);

    header('Content-Type: application/json');

    $result = $user->toArray();
    $result['token'] = create_token('my-example-key', $user->getId());
    echo json_encode($result);
    exit();

} catch (Exception $e) {
    // Failed to get user details
    exit('Oh dear...' . $e->getMessage());
}

Hopefully someone can help me out! Thanks in advance.


Solution

  • Sorry guys, I've been able to solve it myself. I found out that I was missing some URL's to POST to and GET from. After that the examples from Satellizer became clear and was able to use them almost as a carbon copy.