希望得到的效果
在 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 聊聊, 查看更多联系方式