CSRF Cookie在使用axios GET - Laravel 9 Sanctum时未被设置 &



我目前正在尝试使用Laravel (v9.52.4)和Sanctum创建一个简单的身份验证功能。从前端,我目前使用Axios来获取和发布数据。前端和后端API都在本地主机上运行(http://121.0.0.1:8000),但API端点可以通过http://121.0.0.1:8000/api/v1/{endpoint到达这里}

当我尝试登录时,一切似乎都按预期运行,但没有CSRF cookie正在由后端API发送/设置。如果我使用正确的登录凭据(电子邮件+密码),则在后端生成令牌,存储在数据库中,并发送登录成功的响应—当然,如果凭据无效,则不会生成令牌,并且我收到正确的响应。(所以登录逻辑似乎工作得很好,但没有CSRF cookie,我不能在管理子页面上授权自己,所以它只是将我重定向到登录页面,即使成功登录)

我一直在寻找解决办法,但到目前为止还没有运气。您可以找到可能与此问题相关的所有文件/代码片段:

.env(ROOT_URL变量用于在前端创建HTML和Javascript url)

APP_URL=http://127.0.0.1:8000
...
SESSION_DOMAIN = "127.0.0.1:8000"
SANCTUM_STATEFUL_DOMAINS = "127.0.0.1:8000"
ROOT_URL="http://127.0.0.1:8000"

AuthController-/login route使用该控制器的函数

<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use IlluminateSupportFacadesAuth;
use IlluminateHttpResponse;
class AuthController extends Controller
{
public function login(Request $request){
$credentials = [
'email' => $request->email, 
'password' => $request->password
];
if(Auth::attempt($credentials)){
$authUser = Auth::user();
$success['token'] = $authUser->createToken('APIToken')->plainTextToken;
$success['name'] = $authUser->name;
return response()->json(['user' => $success], 200);
}
else {
return response()->json(['error' => "Unauthenticated"], 404);
}
}
public function logout(Request $request, $isAPI = true){
$request->session()->invalidate();
$request->session()->regenerateToken();
auth()->user()->tokens()->delete();
if($isAPI){
return response()->json(['msg' => "user logged out"], 200);
}
return view('admin.login');
}
}

cors.php

'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,

Kernel.php(我已经导入并添加了中间件)

...        
'api' => [
LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful::class,
'throttle:api',
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
...

前端Axios处理程序

const API_ROOT = `${ROOT_URL}/api/v1`
axios.defaults.withCredentials = true
async function loginUser(credentials){ //these credentials are coming from the HTML form inputs
const CSRF = `${ROOT_URL}/sanctum/csrf-cookie`
const LOGIN_URL = `${API_ROOT}/login`
toggleLoader()
await axios.get(CSRF)
await axios.post(LOGIN_URL, credentials)
.then((res) => handleResponse(res.data))
.catch((err) => console.log(err))
.finally(() => toggleLoader())
}
function handleResponse(response){
if(response.user){
console.log(`Logged in as ${response.user.name}`)
window.location.replace(`${ROOT_URL}/admin`)
return
}
console.log('failed to log in')
}

我真的希望有人已经遇到这个问题,可以给我一个帮助之手。谢谢大家的帮助和建议!祝你有美好的一天!旁注:当我使用XAMPP进行本地托管时,身份验证过程(创建令牌、设置cookie和登录)正在工作。然后我将项目移出htdocs目录,并开始使用php artisan serve命令进行托管。除了设置CSRF cookie之外,其他所有内容(数据库、路由等)仍在工作。

我终于找到了解决方案-问题主要与错误配置的域有关。我还在一个实时服务器上部署了这个项目,它在那里也工作得很好。

下面是我在.env中的设置文件,修复了我的问题:

APP_URL=http://127.0.0.1:8000
SESSION_DOMAIN=127.0.0.1
SESSION_DRIVER=cookie
SANCTUM_STATEFUL_DOMAINS=127.0.0.1:8000
ROOT_URL=//127.0.0.1:8000

注意:在获取API时正在使用ROOT_URL !(所以在我的js文件中它看起来像这样://127.0.0.1:8000/api/v1/login)

似乎在URL中,方案和端口(':8000','http',等等…)在哪里显示是非常重要的。

我真的希望这个解决方案能帮助一些人。:)

相关内容

  • 没有找到相关文章

最新更新