Slim框架用来创建REST API, 这篇文章用来解释怎么用JWT来实现REST API安全
使用Composer安装Slim
composer create-project slim/slim-skeleton jwtApp
安装依赖
composer require firebase/php-jwt
composer require tuupola/base62
composer require tuupola/slim-base-auth
composer require tuupola/slim-jwt-auth
composer require tuupola/cors-middleware
配置单入口文件转发
- apach服务器添加
.htaccess
文件
RewriteEngine On
#RewriteBase /api/
RewriteRule .* — [env=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
# Make sure $HTTP_RAW_POST_DATA is deprecated warning does not appear
php_value always_populate_raw_post_data -1
代码编辑
1. 编辑 middleware.php 文件,添加下面的代码.
add(new \Slim\Csrf\Guard);
// Adding dependencies
use Tuupola\Middleware\HttpBasicAuthentication;
$container = $app->getContainer();
$container['logger'] = function($c) {
$logger = new \Monolog\Logger('my_logger');
$file_handler = new \Monolog\Handler\StreamHandler("../logs/app.log");
$logger->pushHandler($file_handler);
return $logger;
};
$container["jwt"] = function ($container) {
return new StdClass;
};
$app->add(new \Slim\Middleware\JwtAuthentication([
"path" => "/",
"logger" => $container['logger'],
"secret" => "123456789helo_secret",
"rules" => [
new \Slim\Middleware\JwtAuthentication\RequestPathRule([
"path" => "/",
"passthrough" => ["/token", "/not-secure", "/home"]
]),
new \Slim\Middleware\JwtAuthentication\RequestMethodRule([
"passthrough" => ["OPTIONS"]
]),
],
"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));
}
]));
2. 打开routes.php
文件.添加下面的代码.
post("/token", function ($request, $response, $args) use ($container){
/* Here generate and return JWT to the client. */
//$valid_scopes = ["read", "write", "delete"]
$requested_scopes = $request->getParsedBody() ?: [];
$now = new DateTime();
$future = new DateTime("+10 minutes");
$server = $request->getServerParams();
$jti = (new Base62)->encode(random_bytes(16));
$payload = [
"iat" => $now->getTimeStamp(),
"exp" => $future->getTimeStamp(),
"jti" => $jti,
"sub" => $server["PHP_AUTH_USER"]
];
$secret = "123456789helo_secret";
$token = JWT::encode($payload, $secret, "HS256");
$data["token"] = $token;
$data["expires"] = $future->getTimeStamp();
return $response->withStatus(201)->withHeader("Content-Type", "application/json")->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
});
$app->get("/secure", function ($request, $response, $args) {
$data = ["status" => 1, 'msg' => "This route is secure!"];
return $response->withStatus(200)->withHeader("Content-Type", "application/json")->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
});
$app->get("/not-secure", function ($request, $response, $args) {
$data = ["status" => 1, 'msg' => "No need of token to access me"];
return $response->withStatus(200)->withHeader("Content-Type", "application/json")->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));
});
$app->post("/formData", function ($request, $response, $args) {
$data = $request->getParsedBody();
$result = ["status" => 1, 'msg' => $data];
// Request with status response
return $this->response->withJson($result, 200);
});
$app->get('/home', function ($request, $response, $args) {
// Sample log message
$this->logger->info("Slim-Skeleton '/' route");
// Render index view
return $this->renderer->render($response, 'index.phtml', ["name" => "Welcome to Trinity Tuts demo Api"]);
});
[![Demo视频](http://upload-images.jianshu.io/upload_images/5941869-67a7e3dbd5fe9b66?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)](http://player.youku.com/embed/XMjY5NDA2MDI4MA== "Demo视频")
地址:
https://v.youku.com/v_show/id_XMzY4ODI2NDUyNA==.html?spm=a2hzp.8244740.0.0
另外这个demo已经无法复现估计是版本的问题,但是已经很好的展示了slim-jwt-auth
的用法了