如何为路由组中的所有请求设置标头

Posted

技术标签:

【中文标题】如何为路由组中的所有请求设置标头【英文标题】:How to set header for all requests in route group 【发布时间】:2017-11-11 04:50:35 【问题描述】:

我正在使用 Laravel 5.4 创建一个 API,它运行良好。我使用了以下中间件 => auth:api 像这样

Route::group(['middleware' => 'auth:api'], function() 
    Route::get('URIValue', ControllerName@action) //Example
);

我已经用 postman 测试过,当请求头包含以下键和值时它运行良好:

授权:Bearer api_token 接受:应用程序/json

当 api_token 无效时,会执行 Handler 类的未认证功能。 laravel 返回的默认响应是

'error' => 'Unauthenticated' // in JSON format

但是当没有设置 Accept 头时,laravel 默认返回一个视图。但是对于 API,视图是不可接受的。

如何强制 laravel 检查是否为路由组中的路由的每个请求设置了正确的 Accept 标头(在这种情况下,该值必须是 => accept/json)?

类似:

protected function mapApiRoutes()

    Route::prefix('api')
          ->middleware('api')
          ->namespace($this->namespace)
          ->header('Accept' => 'application/json') //this
          ->group(base_path('routes/api.php'));

Route::group(['middleware'  => 'auth:api', 
              'headers'     => ['Accept' => 'application/json']
             ], function() 
                    Route::get('URIValue', ControllerName@action) //Example
             );

【问题讨论】:

【参考方案1】:

您可以为此创建一个中间件。

您将检查并强制执行 Accept 标头,以便 Laravel 无论如何都会输出 json..

class WeWantJson

    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    
        $acceptHeader = $request->header('Accept');
        if ($acceptHeader != 'application/json') 
            return response()->json([], 400);
        

        return $next($request);
    

在您的App\Http\Kernel 中,您可以将中间件添加到您的 api 组。那么就不需要在routes/routegroups中手动添加了。


编辑:

无论如何,您也可以添加一个中间件来强制执行 json...

class EnforceJson

    /**
     * Enforce json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    
        $request->headers->set('Accept', 'application/json');

        return $next($request);
    

【讨论】:

我确实想过创建一个中间件,但我正在寻找一个开箱即用的 Laravel 解决方案。如果没有,我想我只需要创建一个与您的类似的中间件。 中间件 laravel 开箱即用的解决方案。我添加了另一个示例,您只需在处理请求之前覆盖接受标头。 哈哈哈,确实如此。我喜欢第二个例子。由于它是一个 API,不妨在每个请求中设置标头以避免错误。 嗯......它不那么严格,出于某种原因,您可能希望稍后接受其他类型。尽管现在这种情况很少发生 :) 我宁愿保持严格并在客户端未正确设置 Accept 标头时输出错误,但这是我的意见。 @Robert 在 Laravel 5.6 中:$request->header('Accept', 'application/json'); 检索值并且不改变请求。所以这是行不通的。这个作品***.com/a/35319899/614277【参考方案2】:

你可以像这样使用简单的中间件

class OnlyAcceptJsonMiddleware

    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    
       // Verify if request is JSON
        if (!$request->expectsJson()) 
            return response(['message' => 'Only JSON requests are allowed'], 406);
        

        return $next($request);
    

在您的 App\Http\Kernel 中,您可以将中间件添加到您的 api 组或您想使用的任何组中。

【讨论】:

以上是关于如何为路由组中的所有请求设置标头的主要内容,如果未能解决你的问题,请参考以下文章

如何为每个 http 调用中的默认请求标头创建 axios 配置?

如何为 HttpClient 请求设置 Content-Type 标头?

PostAsJsonAsync C# - 如何为 POST 请求正确设置标头 - BAD REQUEST 400

如果它出现在MYSQL中的组中,如何为每个值返回'true / false'?

如何为Web请求指定标头

如何为laravel中的所有路由添加默认参数