带有 axios 的 API 请求总是未经 Laravel API 授权
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49884611/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
API requests with axios always unauthorized with Laravel API
提问by K3nzie
I'm working on a personal project using Laravel5.6 and Axioslibrary (standard Laravel 5.6package).
我正在使用Laravel5.6 和Axios库(标准 Laravel 5.6包)进行个人项目。
I need to send first GET then POST request using Laravel's API and axios' http requests, but I'm not using Passport or any library like that since it's an internal API serving only VueJS to obtain stuff from the database.
我需要先使用 Laravel 的 API 和 axios 的 http 请求发送 GET 然后 POST 请求,但我没有使用 Passport 或任何类似的库,因为它是一个内部 API,仅提供 VueJS 以从数据库中获取内容。
If I set my API routes using auth:api
middleware, I always get unauthorized response, whichever is the request type, this is the error output :
如果我使用auth:api
中间件设置我的 API 路由,我总是得到未经授权的响应,无论请求类型是什么,这是错误输出:
Error: Request failed with status code 401
错误:请求失败,状态码为 401
The message :
消息:
message: "Unauthenticated."
But, as I read in the documentation, axios headers are set inside laravel's bootstrap.js
to read the authorization token from meta tags (and the code is there) :
但是,正如我在文档中所读到的,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');
}
While, if needed, here's the http request code :
同时,如果需要,这里是 http 请求代码:
axios.post('/api/latest', formData)
So, why am I unauthenticated if those are set?
那么,如果设置了这些,为什么我未经身份验证?
I've tried removing the auth:api
middleware and, of course, it's working:
我试过删除auth:api
中间件,当然,它正在工作:
- Route::middleware('auth:api')->get('/latest', 'InternalApiController@latestEp');
+ Route::get('/latest', 'InternalApiController@latestEp');
What am I doing wrong?
我究竟做错了什么?
回答by Emile Bergeron
I'm not using Passort or any library like that since it's an internal API serving only VueJS to obtain stuff from the database.
我没有使用 Passort 或任何类似的库,因为它是一个内部 API,只为 VueJS 提供服务以从数据库中获取内容。
If the API is not stateless, meaning that the user is known to be logged in with a standard session cookie, then you can just use the default 'web'
middleware for the API routes.
如果 API 不是无状态的,这意味着已知用户使用标准会话 cookie 登录,那么您可以只使用'web'
API 路由的默认中间件。
In the default RouteServiceProvider
, change the mapApiRoutes
function to use the web
middleware instead:
在 default 中RouteServiceProvider
,将mapApiRoutes
函数更改为使用web
中间件:
protected function mapApiRoutes()
{
Route::prefix('api')
// ->middleware('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
}
That being said, you should really put the API routes behind the default 'auth'
middleware since they're not throttled by default.
话虽如此,您真的应该将 API 路由放在默认'auth'
中间件后面,因为它们默认不受限制。
In the routes/api.php
file:
在routes/api.php
文件中:
Route::group(['middleware' => 'auth'], function() {
Route::get('/latest', 'InternalApiController@latest');
});
And if you want to ensure it's an AJAX request, you can create a simple middleware that checks that the request has the X-Requested-With
header set to XMLHttpRequest
.
如果您想确保它是一个 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);
}
}
And register it within the $routeMiddleware
array inside the \App\Http\Kernel
class.
并将其注册在类内的$routeMiddleware
数组中\App\Http\Kernel
。
protected $routeMiddleware = [
'ajax' => \App\Http\Middleware\RequestIsAjax::class,