This code works, but how can I get the permissions to see the /api content with a get request??
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->add(new \Slim\Middleware\JwtAuthentication([
"path" => "/api",
"secret" => "1234"
]));
$app->get('/api', function (Request $request, Response $response) {
echo "Hi";
});
$app->get('/teste', function (Request $request, Response $response) {
echo "Hi";
});
$app->run();
1. Generate Token
Using firebase/php-jwt
$payload = [
"sub" => "user#example.com"
];
$token = JWT::encode($payload,'JWT-secret-key');
2. .htaccess Changes
If using Apache add the following to the .htaccess file. Otherwise PHP wont have access to Authorization: Bearer header
RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
3. Middleware
$app->add(new \Slim\Middleware\JwtAuthentication([
"path" => "/api",
"passthrough" => ["/teste"],
"secret" => "JWT-secret-key",
"secure" => false,
"callback" => function ($request, $response, $arguments) use ($container) {
$container["jwt"] = $arguments["decoded"];
},
"error" => function ($request, $response, $arguments) {
$data["status"] = "0";
$data["message"] = $arguments["message"];
$data["data"] = "";
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
]));
4. Correct Request
5. Wrong Token Request
Reference Link
i used Authorization: Bearer Mykey , the key need to be encode in jwt mode
Related
I'm trying to upgrade my website's code from Slim v2 to v4. I'm not a hardcore programmer so I'm facing issues. In Slim v2 I had some middleware where I was able to assign parameters to the Twig view before the route code executed. Now I'm trying to manage the same with Slim v4 but without success.
So this is a test code:
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Factory\AppFactory;
use Slim\Views\Twig;
use Slim\Routing\RouteContext;
require 'vendor/autoload.php';
require 'config.php';
lib\Cookie::init();
$container = new \DI\Container();
$container->set('view', function($container) {
return Twig::create(__DIR__ . '/views');
});
$container->set('flash', function ($container) {
return new \Slim\Flash\Messages();
});
$container->get('view')->getEnvironment()->addGlobal('flash', $container->get('flash'));
AppFactory::setContainer($container);
$app = AppFactory::create();
$app->addErrorMiddleware(true, false, false);
$fb = new Facebook\Facebook([
'app_id' => '...',
'app_secret' => '...',
'default_graph_version' => '...',
]);
$beforeMiddleware = function (Request $request, RequestHandler $handler) use ($fb) {
$response = $handler->handle($request);
if (!isset($_SESSION['fbuser'])) {
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email'];
$loginUrl = $helper->getLoginUrl('...', $permissions);
$this->get('view')->offsetSet('fbloginurl', $loginUrl);
}
else {
$this->get('view')->offsetSet('fbuser', $_SESSION['fbuser']);
}
$uri = $request->getUri();
$this->get('view')->offsetSet('currenturl', $uri);
return $response;
};
$app->add($beforeMiddleware);
$app->get('/test', function (Request $request, Response $response, $args) {
$oViewParams = new \lib\ViewParams("home", "", "", "", "");
$oProfession = new \models\Profession();
$oBlogPost = new models\BlogPost();
$oBlogTopic = new models\BlogTopic();
$professions = $oProfession->getProfessionsWithLimit(14);
$posts = $oBlogPost->getMainPagePosts();
echo $this->get('view')->offsetGet('fbloginurl');
$params = array('professions' => $professions,
'posts' => $posts,
'viewp' => $oViewParams->getMassParams());
return $this->get('view')->render($response, 'index.html', $params);
});
$app->run();
When I use echo $this->get('view')->offsetGet('fbloginurl'); within the middleware it shows up. When I use the same within the route there is nothing show up...
The next code in the chain of middleware (or your routes) is called when you have...
$response = $handler->handle($request);
As this is before you set any of the values you want to use in twig, they aren't yet set. Move the above line after setting these value and the values should then be available to the rest of the code.
Hi i want to consume a service and i use laravel 5.x with guzzle with this code i can send request and i use the correct api-key but i always obtain 403 forbidden....
public function searchP(Request $request) {
$targa = request('targa');
$client = new \GuzzleHttp\Client();
$url = 'https://xxx.it/api/xxx/xxx-number/'.$targa.'/xxx-xxxx';
$api_key ='xxxxxcheepohxxxx';
try {
$response = $client->request(
'GET',
$url,
['auth' => [null, $api_key]]);
} catch (RequestException $e) {
var_dump($e->getResponse()->getBody()->getContent());
}
// Get JSON
$result = $response->json();
}
Why? I cannot understand
In postman i write in the AUTHORIZATION label this
key : x-apikey
value: xxxxxcheepohxxxx
Add to header
and it works.
i also tried this
.... try {
$response = $client->request('GET',$url,[
'headers' => [
'x-apikey', $api_key
]
]);
} catch .....
but doesn't work
Thx
it should be this, you have a typo
.... try {
$response = $client->request('GET',$url,[
'headers' => [
'x-apikey'=> $api_key
]
]);
} catch .....
I am working on a slim REST API and I want to secure it with JWT Token. I try a lot of tutorials and I am anable to make things work.
I use :
slim 4.*
slim/psr7 0.6.0
tuupola/slim-jwt-auth ^3.4
tuupola/cors-middleware ^1.1
Ubuntu 19.10 and Xampp
I have have 2 routes (POST /login and GET /api/test)
I want to be able to use the /login route without token and the other one with a token.
So I wrote :
$app->add(new Tuupola\Middleware\JwtAuthentication([
"path" => "/api",
"secret" => getenv ("SPROUTCH_TOKEN"),
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
},
]));
In that case nothing is secure so I tried this :
$app->add(new Tuupola\Middleware\JwtAuthentication([
"secret" => getenv ("SPROUTCH_TOKEN"),
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
},
]));
And of course I can't access anything.
The proble was just that the "path" key takes only absolute path
From the question above, I have api/user that contains get, post, put, and delete methods. Is it possible to have passthrough on a specific method?
Example, the public method only is get and the rest needs a token to use that method?
Thank you for your answer.
$app->add(new \Slim\Middleware\JwtAuthentication([
"path" => ["/api", "/admin"],
"passthrough" => ["/api/login", "/admin/ping", "/api/user"],
"algorithm" => "HS256",
"secret" => getenv("JWT_SECRET"),
"callback" => function ($request, $response, $arguments) use ($container) {
$container["jwt"] = $arguments["decoded"];
},
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}]));
By default JWT Authentication middleware does not authenticate OPTIONS requests. To also allow unauthenticated GET requests you can manually add it to the RequestMethodRule. Your example code would become something like following.
require __DIR__ . "/vendor/autoload.php";
$app = new \Slim\App;
$container = $app->getContainer();
$app->add(new \Slim\Middleware\JwtAuthentication([
"path" => ["/api"],
"secret" => getenv("JWT_SECRET"),
"callback" => function ($request, $response, $arguments) use ($container) {
$container["jwt"] = $arguments["decoded"];
},
"rules" => [
new \Slim\Middleware\JwtAuthentication\RequestMethodRule([
"passthrough" => ["OPTIONS", "GET"]
])
],
"error" => function ($request, $response, $arguments) {
$data["status"] = "error";
$data["message"] = $arguments["message"];
return $response
->withHeader("Content-Type", "application/json")
->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
}
]));
$app->get("/api/user", function ($request, $response) {
print "Hello\n\n";
});
$app->post("/api/user", function ($request, $response) {
print "Hello\n\n";
});
$app->run();
This would yield.
$ curl --request GET --include http://127.0.0.1:8080/api/user
HTTP/1.1 200 OK
Host: 127.0.0.1:8080
Connection: close
X-Powered-By: PHP/7.0.12
Content-Type: text/html; charset=UTF-8
Content-Length: 7
Hello
$ curl --request POST --include http://127.0.0.1:8080/api/user
HTTP/1.1 401 Unauthorized
Host: 127.0.0.1:8080
Connection: close
X-Powered-By: PHP/7.0.12
Content-Type: application/json
Content-Length: 59
{
"status": "error",
"message": "Token not found"
}
Yes, you can use Slim Middleware and group authorized routes together and add the middleware to the group:
$validateUser = function($request,$response,$next) {
$token = $_COOKIE['token'];
$token = JWT::decode($token,$secret,['HS256']);
if ($token->user->isAdmin) {
return $next($request,$response);
}
return $response->withStatus(403)->withJson(array('message' => 'Forbidden'));
};
$app->get('/api/user',function($request,$response) {
return $response->withJson(array('message' => 'Public route'));
});
$app->group('/api/user',function() {
$this->delete('','');
$this->post('','');
$this->patch('','');
})->add($validateUser);
When I submit a from action to this url, and also test this api via Postman. It is not printing POST data.
But get method is working.
$app = new \Slim\App;
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
$app->add(new \Slim\Middleware\JwtAuthentication([
//"secure" => false,
//"relaxed" => ["localhost", "api.f2f.dev"],
"header" => "X-Token",
"path" => ["/v2"],
"passthrough" => ["/v1/api/token/", "/test", "/v1"],
"secret" => getenv("TOKEN_SECRET")
]));
$app->post("/v1/app/register", function ($request, $response, $arguments) {
return $allPostPutVars = $request->getParsedBody();
});
I couldn't find the issue i this. But unparsed data is able to print.
Any help is welcome. Any post method on Slim 3 is also welcomed.
Thank you.
Your callback should return response object that implements Psr\Http\Message\ResponseInterface. It doesn't. So, as an example:
$app->post("/v1/app/register", function ($request, $response, $arguments) {
$params = $request->getParams();
return $response->getBody()->write('You have posted '.count($params).' parameters.');
});
Sometimes you need a quick and dirty check. Then you can do the following:
$app->post("/v1/app/register", function ($request, $response, $arguments) {
$params = $request->getParams();
print_r($params);
die();
});