我尝试使用Laravel构建的REST API。但是由于令牌不匹配,对POSTMAN的调用被拒绝。我想我需要在header中包含CSRF令牌。但我需要加密的吗?当我插入这个令牌时,我仍然得到一个令牌不匹配的错误。
我检索我的令牌使用:
$encrypter = app('IlluminateEncryptionEncrypter');
$encrypted_token = $encrypter->encrypt(csrf_token());
return $encrypted_token;
但是这应该在每次刷新时改变吗?
如果您不使用表单-例如API -您可以按照下面的步骤https://gist.github.com/ethanstenis/3cc78c1d097680ac7ef0:
基本上,将以下内容添加到您的叶片或小枝标题
<meta name="csrf-token" content="{{ csrf_token() }}">
安装邮差拦截器如果还没有安装,并打开它
然后,在浏览器中登录到站点(您需要获得授权),并检查元素或查看源以检索令牌
在Postman中,根据需要设置GET/POST等,并在header中创建一个新的pair
X-CSRF-TOKEN tokenvaluetobeinserted235kwgeiOIulgsk
有些人建议在测试API时关闭CSRF令牌,但这样你就没有真正测试它了,对吗?
如果你发现你仍然有错误,检查响应返回使用preview
作为Laravel倾向于相当明确的错误消息。如果没有返回,检查您的php_error.log
(无论它叫什么)。
ps 2018年10月-我现在使用Laravel护照处理API注册,登录和用户令牌-值得一看!
进入app/Http/Middleware/VerifyCsrfToken.php
并添加这些值
protected $except = [
'/api/*'
];
是的,每次刷新它都会改变。你应该把它放在视图中,当你发布时,它需要作为"_token"post变量的值发送。
如果您只是使用标准的POST,只需在表单中添加以下内容:
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
如果您正在使用AJAX,请确保获取_token的值并将其与请求一起传递。
REF: http://laravel.com/docs/5.1/routing#csrf-protection
Use Postman
对任何包含
的页面进行GET请求<meta name="csrf-token" content="{{ csrf_token() }}">
从响应中复制值。
为POST请求添加标题字段:
"X-CSRF-TOKEN: "copied_token_in_previous_get_response"
我在Postman环境中使用baseURL
变量时出现了此错误。事实证明,我在最后没有/api
的情况下调用了网站的URL。听起来很傻,但为了消除用户错误,请确保检查请求URL是否基于:
✅https://<your-site-url>/api
:
❌https://<your-site-url>
当我遇到错误时,我正在遵循本教程。我正在向我的web.php中的路由发出请求,而get请求成功时,post请求即使在添加X-XSRF-TOKEN标头后也返回令牌不匹配错误。我遇到了这篇文章,建议在AppHttpMiddlewareVerifyCsrfToken::class行中对web.php中定义的路由进行post请求时,在AppHttp kernel.php文件中的web中间件组中评论。这对我很有效。只是不要忘记在完成测试后取消注释。
'web' => [
AppHttpMiddlewareEncryptCookies::class,
IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,
IlluminateSessionMiddlewareStartSession::class,
IlluminateViewMiddlewareShareErrorsFromSession::class,
// AppHttpMiddlewareVerifyCsrfToken::class,
IlluminateRoutingMiddlewareSubstituteBindings::class,
AppHttpMiddlewareHandleInertiaRequests::class,
IlluminateHttpMiddlewareAddLinkHeadersForPreloadedAssets::class,
],
如果你让REST API
使用api.php
写路由,而不是web.php
,根据Laravel文档web.php
是为网站写路由,这就是为什么你看到csrf-token错误,而使用它像API,所以对于API,我们有 api.php
文件不会给你一个csrf-token错误。
我刚刚遇到了同样的问题,这个答案最终帮助我解决了它:https://stackoverflow.com/a/67435592/11854580
显然CSRF令牌需要在每次POST请求时更新。(不是每个GET请求都这样。)您可以使用本教程中解释的Postman中的预请求脚本来解决此问题:https://blog.codecourse.com/laravel-sanctum-airlock-with-postman/
对于最近访问此
的任何人供应商包也使用.env
(SESSION_DOMAIN
和SANCTUM_STATEFUL_DOMAINS
),所以有时会有奇怪的行为。
从.env
中删除这些
# SESSION_DOMAIN=
# SANCTUM_STATEFUL_DOMAINS=
将这些添加到.env
。确保URL是完整的(方案,域和端口(在开发时))
APP_URL=http://localhost:8000
FRONTEND_URLS=http://localhost:5173,http://localhost:5174,http://localhost:5175,http://localhost:5176
将这些添加到config/cors.php
return [
'paths' => ['*'],
'allowed_methods' => ['*'],
'allowed_origins' => explode(',', env('FRONTEND_URLS')),
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
]
将这些添加到config/sanctum.php
return [
...
'stateful' => explode(
',',
env(
'SANCTUM_STATEFUL_DOMAINS',
sprintf(
'%s%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : '',
env('FRONTEND_URLS')
? implode(
',',
array_map(function ($url) {
return parse_url($url, PHP_URL_HOST);
}, explode(',', env('FRONTEND_URLS')))
)
: ''
)
)
),
...
]
确保这一行出现在kernel.php
protected $middlewareGroups = [
'web' => [
...
],
'api' => [
LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class, // <---
...
],
];
不要忘记在开发和服务器中清除缓存。
php artisan config:clear
php artisan route:clear
php artisan cache:clear
我的解决方案不是那么方便,但我已经测试过的Laravel 8,9,10工作。你也不需要改变Laravel的初始值:
-
创建名为xrss - token(或任何您喜欢的名称)的POSTMAN环境变量
-
创建一个GET方法访问
/sanctum/csrf-cookie -
在测试部分(POSTMAN)中,输入以下代码片段:
pm.environment.set("XSRF-TOKEN"pm.cookies.get("XSRF-TOKEN");
这会将从后端生成的令牌设置为Postman环境变量XSRF-TOKEN。
- 在每个请求中,在头文件中输入X-XSRF-TOKEN变量,除其他键外,设置值为{{XSRF-TOKEN}}
完成! !
每次收到CSRF missed match
消息。您在第2步重新运行请求以生成新的令牌。
希望这对你有帮助!
将/api添加到url中应该可以解决大多数人只是测试他们的api…如。https://www.yoursite.com/api/register