如何让Laravel的搜索路由仅允许通过JavaScript访问?
好问题!要阻止用户直接在浏览器地址栏访问你的搜索接口,只允许AJAX请求调用,这里有几种简单有效的方案,你可以根据需求选择:
方法1:检查AJAX请求头(最直接便捷)
Laravel内置了判断AJAX请求的方法,只需在你的search方法开头加一段校验即可:
public function search(Request $request) { // 拦截非AJAX请求 if (!$request->ajax()) { // 可选:返回403禁止访问,或者重定向到首页 abort(403, 'Unauthorized access.'); // 或者用 return redirect('/'); 引导用户回到正常页面 } // 你的搜索逻辑代码... $results = // 执行查询并获取结果 return response()->json($results); }
原理很简单:jQuery的autocomplete发起请求时,会自动在请求头里带上X-Requested-With: XMLHttpRequest,Laravel的$request->ajax()就是检测这个标识。而用户直接在浏览器输入URL时,这个请求头是不存在的,自然会被拦截。
方法2:改用POST请求(安全性更高)
如果不想保留GET请求的路由,可以把接口改成POST类型,这样直接访问GET的/search会直接返回404/405错误。
首先修改路由:
Route::post('/search', 'IndexController@search')->name('index.search');
然后调整JavaScript代码,指定请求类型为POST,并带上Laravel要求的CSRF令牌:
$(function() { $('#terms').autocomplete({ source: function(request, response) { $.ajax({ url: 'search', type: 'POST', data: { term: request.term, _token: '{{ csrf_token() }}' // 必须带上CSRF令牌验证 }, success: function(data) { response(data); } }); } }); });
这种方式下,不仅直接访问GET会被拒绝,就算有人用工具模拟POST请求,没有正确的CSRF令牌也会被Laravel拦截,安全性更强。
方法3:双重校验(极致防护)
如果想要最严格的限制,可以把上面两种方法结合起来:既检查AJAX请求头,又使用POST请求。这样能最大程度阻挡非预期的访问。
补充说明:如果担心有人手动伪造X-Requested-With头,还可以额外校验请求的Referer来源(比如用$request->header('Referer')判断是否来自你的域名),但这个头可以被篡改,仅作为辅助校验即可,普通场景下前两种方法已经足够。
内容的提问来源于stack exchange,提问作者Barret Wallace
相关产品推荐
相关产品推荐

