我正在使用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');
我做错了什么?
答案 0 :(得分:9)
我没有使用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,
答案 1 :(得分:2)
在 Laravel 8 中,当我尝试从后端 api 请求某些内容时收到 401 错误。按照接受的答案让我接近,但它仍然没有用。我相信这是因为我在子域上的仪表板为 users.mydomain.tld
,而我使用 Axios 的位置在主域上为 mydomain.tld/some/path
。问题是会话 cookie 的路径。重新配置时,您需要清除所有 cookie(开发工具栏)。然后在进行更改后像往常一样重新登录。否则,cookie 会被弄乱,您将看不到它已修复,或者您在清除它们之前根本无法登录。
我恢复了我所做的所有更改(遵循已接受的答案)并确定 SESSION_DOMAIN
环境变量是关键因素,至少在主要用户区域位于子域中时是这样。< /p>
在您的 .env
文件中:
SESSION_DOMAIN=".yourdomain.tld"
在 app/Providers/RouteServiceProvider.php
中,在 api
方法中将 web
更改为 boot()
:
Route::prefix('api')
//->middleware('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
在routes/api.php
中:
Route::middleware('auth')->get('/user', function (Request $request) {
return $request->user();
});
在您的 resources/js/bootstrap.js
中:
window.axios.defaults.withCredentials = true;
修改bootstrap.js
文件后,需要再次运行npm run dev
重新编译。
现在,您应该可以在前端 JavaScript 中使用 Axios。无论是 jQuery 还是 Vue,无论您使用什么。
axios.get('/api/user')
.then(response => console.dir(response.data))
.catch(error => console.log(error));
答案 2 :(得分:0)
CSRF-token与授权令牌不同。您很可能需要手动添加授权令牌,这可能与this相似,具体取决于您的授权方式。