在某些时候,为了数据的安全和保密性,需要对来回的数据进行加密处理。如果是 laravel 框架,中间件绝对是个好东西。
一波操作
laravel 中间件包含一个完整的工作流,即请求前中间件(request)和请求后中间件(response)。在我们这次的场景中,刚好很好的用到了整个流程。
操作开始:
# 执行该命令,会自动生成 SecretMiddleware 中间件
php artisan make:middleware SecretMiddleware
# 将 SecretMiddleware 中间件注册别名
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'secret' => \App\Http\Middleware\SecretMiddleware::class,
];
# 因为我们是对整个接口文件的请求进行加解密。所以在中间件组中的 api 中添加该别名
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'auth:api',
'secret'
],
];
# 这样,所有的 api 请求都会应用该中间件。
# 如果想让所有的请求都应用,则只需要将 \App\Http\Middleware\SecretMiddleware::class 绑定到 $middleware 中。
# 如果只想某个路由单独使用该中间件可以在具体某个路由处指定该中间件, 如下
Route::get('xxx', 'xxx')->middleware('secret');
到此,中间件的注册和绑定已经完成。下一步就是具体的中间件逻辑了。
中间件逻辑
我们可以看到,在生的中间件文件中,已经有了 handler 方法。
public function handle($request, Closure $next) {
return $next($request);
}
# 这样等于建了一个空行为的中间件,啥也不做。既然我们的目的是想对请求的数据进行解密,对返回出去的数据进行加密。那么就这样操作。
public function handle($request, Closure $next)
{
if (count($request->input()) > 0) {
$body = Arr::first(array_keys($request->input()));
if ($body) {
$body = Aes::decrypt($body);
parse_str($body, $input);
$request->merge($input);
}
}
$input = $request->input();
# 对 input 里的数据进行解密,解密后的数据再继续给到 request 中
# 解密后的数据
$body = 'xxxxxx';
parse_str($body, $input);
$request->merge($input);
$response = $next($request);
# 拿到需要返回的数据,然后进行加密
$content = $response->getContent();
if ($content) {
$content = json_decode($content, true);
# 对 content 进行加密处理
$response->setContent(json_encode($content));
}
return $response;
}
在这里的一个分界线就是 $next($request) ,之前,进行 request 的数据处理,之后,进行 response 的数据处理。
因为多端进行加解密,这里使用 aes。