我目前正在尝试使用 Laravel (v9.52.4) 和 Sanctum 创建一个简单的身份验证功能。从前端我目前使用 Axios 来获取和发布数据。前端和后端 API 都在本地主机 (http://121.0.0.1:8000) 上运行,但 API 端点可以在http://121.0.0.1:8000/api/v1/{endpoint 这里}
当我尝试登录时,一切似乎都按预期运行,但是 后端 API 没有发送/设置 CSRF cookie。 如果我使用正确的登录凭据(电子邮件 + 密码),令牌将在后端生成,存储在数据库中并发送登录成功的响应 - 当然,如果凭据无效,则不会生成令牌,我会收到正确的响应。 (因此登录逻辑似乎工作正常,但没有 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 路由使用此控制器的功能
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Response;
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' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::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 之外,其他一切(数据库、路由等)仍在工作。