Laravel ajax 请求 api 的权限控制

文章目录

    希望得到的效果

    在 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 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式