Laravel ajax 请求 api 的权限控制

更新日期: 2019-01-07 阅读次数: 8624 分类: Laravel

希望得到的效果

在 web 网站中,一些页面的数据需要登录之后才能拉取。

  • 在用户未登录时,ajax 请求某个 API,后台报 401 未授权错误
  • 在用户登录后,可以正常 ajax 调用该 API

是否登录需要使用当前 web 的登录状态,所以不能使用类型小程序那种 token 的方案。

解决方法

修改 app/Http/Kernel.php middlewareGroups 中 api 的配置,添加两行:

\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,

添加这两行的目的是针对 API 接口启用 session, 以判断用户是否登录。

然后在路由 route/api.php 中添加登录限制

Route::get('addresses', [
    'uses' => 'AddressController@addresses',
])->middleware('auth');

这样使用 ajax 请求 /api/addressess 就能看到限制效果了。

实现的原理

看了网上一些贴出来的解决方案,大概明白了这种实现的原理。例如,一种原始的解决方案,就是自定义一个 auth middleware

class Authenticate
{
    public function handle($request, Closure $next)
    {
        if ($this->auth->guest()) {
            if ($request->ajax()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->guest('login');
            }
        }
      return $next($request);
    }
}

$request->ajax() 的实现原理呢?

Symfony\Component\HttpFoundation\Request::isXmlHttpRequest() is a simply utility-method that checks whether HTTP request came up with X-Requested-With header with value XMLHttpRequest. So it's as reliable as X-Requested-With header is.

也就是说,ajax 请求是可以通过请求头中是否包含

X-Requested-With: XMLHttpRequest

来判断。在 Chrome 中看了一些,确实如此。而浏览器地址栏输入的方式打开,是没有这个 header 信息的。所以会被判定为正常的 web 请求,直接跳转到 login 页面。

参考

https://laravel.io/forum/02-09-2016-52-ajax-auth-not-picking-up-session

关于作者 🌱

我是来自山东烟台的一名开发者,有敢兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊, 查看更多联系方式