Hi there : ),
I am currently using Slim v3 and this package. I successfully integrated the implementation for my API routes.
However, in a confirmation email I am using a link like this (see below) and I would like to know if there is a way to extract the token from the URL.:
http://site.com/confirm/{{access_token_with_specific_scope}}
If this isn't the place to ask, I apologize.
Best regards,
Guillaume R.
If I understand correctly you are sending this email for some kind of account activation?
In any case, getting the access token from a URL is outside of the scope of this library.
I can advice you to do the following things:
For extracting any data from a request in Slim I would advise to use a middleware specific to your application which knows where a token should be present. You can find examples on how to do this in the official documentation, also describing how to pass variables;
http://www.slimframework.com/docs/v3/concepts/middleware.html
If the primary function of your endpoint is to validate/do something with the access token then you can write the logic to extract the access token in your controller itself. This is assuming you take the advice to move the access token to a query parameter or let javascript do a separate request to the server.
OR If you keep your URL structure as given you should extract the parameter from the path when defining the route for your controller / handler. This is explained in the "First Application" tutorial;
https://www.slimframework.com/docs/v3/tutorial/first-app.html#create-the-application
https://www.slimframework.com/docs/v3/objects/router.html#how-to-create-routes
A route for you would look something like this;
$app->get('/confirm/{token}', function (Request $request, Response $response, array $args) {
$name = $args['token'];
$response->getBody()->write("Your token is, $token");
return $response;
});
Again, I would advise against keeping the token in the path part of your URL; here is some more specific documentation on how you can transfer variables between middleware and controller;
https://www.slimframework.com/docs/v3/objects/request.html#attributes
Hi, sorry for the late response.
Ok so, I think I might have wrongly explained my problem. It isn't how to get the token from somewhere but how to manually validate a request from a custom token variable.
I mean, I don't get the token from the Authorization: Bearer token, so the request can't be validated. So, my point is, how to pass the token to the validation process from a string (that I get from the url or whatever) ?
Hope I explained a bit better this time ^^'
$app->get('/confirm/', function (Request $request, Response $response, array $args) {
$token = $args['token']; // get the token from somewhere
// Something here to do to authorize the request manually
// if (!$app->authorizeFromString($token)) {
// return false;
// }
$response->getBody()->write("authorized");
return $response;
});
Thanks for the response : )
That does make more sense. I think I know what you're after. You want to know how to validate the access token in a non-standard situation.
The library supplies a middleware for the standard situation where a bearer token is validated;
https://oauth2.thephpleague.com/resource-server/securing-your-api/
To validate the token in a request in a non-standard way, I would simply add a middleware which modifies the request to include the token in the Authorization header as a bearer token, before this supplied middleware processes the request.
This could be as easy as;
return $next($request->withHeader('Authorization', "Bearer $token"), $response);
Though you would need to retrieve $token from the request before this, and you might want to make modifications to the path and catch requests lacking a token in the correct position maybe.
Doing that you should be able to use the supplied middleware to validate the request. If this is not an option I would suggest writing your own middleware/jwt validator. There are multiple packages available to make it easier.
Thanks for your responses with this @sg3s - much appreciated for your assistance. I think @sg3s has covered most of what you will need. I would also suggest you look at the BearerTokenValidator class to find out how the OAuth server validates a token, specifically the validateAuthorization() function.
Most of the validation is handled by our third party JWT library. We use lcobucci/jwt.
Thank you so much for your responses. This helped me a lot.
I did not tought about this simple solution that is setting the token in the header after getting it from the url. This works well.
Have a good day :) .
Hey, it's me again !
I'm not sure if I can ask on top of this question (if not, I still can create a new issue/question ^^) but; I'm trying to manually generate an access token. I followed the methods issueAccessToken, getNewToken and tried to implement it but without success (can't find any jwt token). Is there a link, a resource for this ? I tried a research in the issues but couldn't find anything relevant.
This is my code and it's response (sorry, idk how to indent the response quote) :
$app->get('/test', function() use ($app) {
$client = new ClientEntity();
$client->setIdentifier('dashboard');
$scope = new ScopeEntity();
$scope->setIdentifier('dashboard');
$date = new DateTime(date('Y-m-d H:i:s'));
$date->add(new DateInterval('P10D'));
$accessToken = new AccessTokenEntity();
$accessToken->setIdentifier(bin2hex(random_bytes(40)));
$accessToken->setClient($client);
$accessToken->setExpiryDateTime($date);
$accessToken->addScope($scope);
$accessToken->setUserIdentifier('2348234');
die(var_dump($accessToken));
});
object(App\Models\Oauth\AccessTokenEntity)#148 (5) {
["scopes":protected]=>
array(1) {
["dashboard"]=>
object(App\Models\Oauth\ScopeEntity)#141 (1) {
["identifier":protected]=>
string(9) "dashboard"
}
}
["expiryDateTime":protected]=>
object(DateTime)#149 (3) {
["date"]=>
string(26) "2019-06-15 14:16:21.000000"
["timezone_type"]=>
int(3)
["timezone"]=>
string(3) "UTC"
}
["userIdentifier":protected]=>
string(7) "2348234"
["client":protected]=>
object(App\Models\Oauth\ClientEntity)#154 (3) {
["identifier":protected]=>
string(9) "dashboard"
["name":protected]=>
NULL
["redirectUri":protected]=>
NULL
}
["identifier":protected]=>
string(80) "5ff6fdfd197702ffd4d2510bcd57a3d1f971a0b89c2ba01270cacfeb2804ce23d6651c81474ab4db"
}
Any help would be appreciated :).
Ok, after digging for a while, I found that I had to ->convertToJWT() . This now works properly. Thank you anyway :).