我正在使用Laravel 5.6和Axios库(标准Laravel 5.6包)开展个人项目。
我需要使用Laravel的API和axios的http请求发送第一个GET然后发送POST请求,但是我没有使用Passport或任何类似的库,因为它是一个内部API,只提供VueJS来从数据库中获取内容。
如果我使用auth:api
中间件设置我的API路由,我总是得到未经授权的响应,无论哪个是请求类型,这都是错误输出:
错误:请求失败,状态码为401
消息:
message: "Unauthenticated."
但是,正如我在文档中所读到的那样,axios头文件设置在laravel的bootstrap.js
中,以便从元标记中读取授权令牌(代码就在那里):
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
// further down the file...
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
虽然如果需要,这里是http请求代码:
axios.post('/api/latest', formData)
那么,为什么我没有认证,如果这些设置?
我已经尝试删除auth:api
中间件,当然,它正在工作:
- Route::middleware('auth:api')->get('/latest', 'InternalApiController@latestEp');
+ Route::get('/latest', 'InternalApiController@latestEp');
我究竟做错了什么?
我没有使用Passort或类似的任何库,因为它是一个内部API,只提供VueJS来从数据库中获取东西。
如果API不是无状态的,意味着已知用户使用标准会话cookie登录,那么您可以使用默认的'web'
中间件作为API路由。
在默认的RouteServiceProvider
中,更改mapApiRoutes
函数以使用web
中间件:
protected function mapApiRoutes()
{
Route::prefix('api')
// ->middleware('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
话虽这么说,你应该把API路由放在默认的'auth'
中间件之后,因为默认情况下它们没有被限制。
在routes/api.php
文件中:
Route::group(['middleware' => 'auth'], function() {
Route::get('/latest', 'InternalApiController@latest');
});
如果你想确保它是一个AJAX请求,你可以创建一个简单的中间件来检查请求是否将X-Requested-With
头设置为XMLHttpRequest
。
class RequestIsAjax
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (!$request->ajax()) {
return redirect()->route('login.index');
}
return $next($request);
}
}
并在$routeMiddleware
类中的\App\Http\Kernel
数组中注册它。
protected $routeMiddleware = [
'ajax' => \App\Http\Middleware\RequestIsAjax::class,
CSRF令牌与授权令牌不同。您很可能需要手动添加授权令牌,这可能与this相似,具体取决于您的授权方法。