🚀 مُصادَق: تحديث برمجي جديد 2026-05-03 15:51
This commit is contained in:
@@ -36,20 +36,15 @@ final class AuthController
|
||||
return;
|
||||
}
|
||||
|
||||
// Set refresh token in HttpOnly cookie
|
||||
setcookie('refresh_token', $result['refresh_token'], [
|
||||
'expires' => time() + (60 * 60 * 24 * 7),
|
||||
'path' => '/api/v1/auth/refresh',
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => true
|
||||
]);
|
||||
$this->setAuthCookies($result);
|
||||
|
||||
unset($result['refresh_token']);
|
||||
// Backward compatibility for existing non-browser clients
|
||||
$responseData = $result;
|
||||
unset($responseData['refresh_token']);
|
||||
|
||||
Response::json([
|
||||
'success' => true,
|
||||
'data' => $result,
|
||||
'data' => $responseData,
|
||||
'message' => 'تم تسجيل الدخول بنجاح'
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
@@ -88,14 +83,10 @@ final class AuthController
|
||||
}
|
||||
}
|
||||
|
||||
// Clear refresh token cookie
|
||||
setcookie('refresh_token', '', [
|
||||
'expires' => time() - 3600,
|
||||
'path' => '/api/v1/auth/refresh',
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => true
|
||||
]);
|
||||
// Clear auth cookies
|
||||
setcookie('refresh_token', '', ['expires' => time() - 3600, 'path' => '/api/v1/auth/refresh', 'httponly' => true, 'samesite' => 'Strict', 'secure' => true]);
|
||||
setcookie('access_token', '', ['expires' => time() - 3600, 'path' => '/', 'httponly' => true, 'samesite' => 'Strict', 'secure' => true]);
|
||||
setcookie('csrf_token', '', ['expires' => time() - 3600, 'path' => '/', 'httponly' => false, 'samesite' => 'Strict', 'secure' => true]);
|
||||
|
||||
Response::json([
|
||||
'success' => true,
|
||||
@@ -115,20 +106,15 @@ final class AuthController
|
||||
try {
|
||||
$result = $this->authService->refresh($refreshToken);
|
||||
|
||||
// Set new refresh token in HttpOnly cookie
|
||||
setcookie('refresh_token', $result['refresh_token'], [
|
||||
'expires' => time() + (60 * 60 * 24 * 7),
|
||||
'path' => '/api/v1/auth/refresh',
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => true
|
||||
]);
|
||||
$this->setAuthCookies($result);
|
||||
|
||||
unset($result['refresh_token']);
|
||||
// Backward compatibility
|
||||
$responseData = $result;
|
||||
unset($responseData['refresh_token']);
|
||||
|
||||
Response::json([
|
||||
'success' => true,
|
||||
'data' => $result,
|
||||
'data' => $responseData,
|
||||
'message' => 'تم تجديد الجلسة بنجاح'
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
@@ -140,20 +126,15 @@ final class AuthController
|
||||
try {
|
||||
$result = $this->authService->register($request->getBody());
|
||||
|
||||
// Set refresh token in HttpOnly cookie
|
||||
setcookie('refresh_token', $result['refresh_token'], [
|
||||
'expires' => time() + (60 * 60 * 24 * 7),
|
||||
'path' => '/api/v1/auth/refresh',
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => true
|
||||
]);
|
||||
$this->setAuthCookies($result);
|
||||
|
||||
unset($result['refresh_token']);
|
||||
// Backward compatibility
|
||||
$responseData = $result;
|
||||
unset($responseData['refresh_token']);
|
||||
|
||||
Response::json([
|
||||
'success' => true,
|
||||
'data' => $result,
|
||||
'data' => $responseData,
|
||||
'message' => 'تم إنشاء الحساب وتسجيل الدخول بنجاح'
|
||||
]);
|
||||
} catch (Throwable $e) {
|
||||
@@ -226,19 +207,24 @@ final class AuthController
|
||||
return;
|
||||
}
|
||||
|
||||
// Re-issue a full login session after successful 2FA.
|
||||
$stmt = $db->prepare("SELECT email FROM users WHERE id = ?");
|
||||
$stmt = $db->prepare("SELECT * FROM users WHERE id = ?");
|
||||
$stmt->execute([$userId]);
|
||||
$email = $stmt->fetchColumn();
|
||||
if (!$email) {
|
||||
$user = $stmt->fetch();
|
||||
if (!$user) {
|
||||
Response::error('المستخدم غير موجود', 'NOT_FOUND', 404);
|
||||
return;
|
||||
}
|
||||
|
||||
$result = $this->authService->createSession($user);
|
||||
$this->setAuthCookies($result);
|
||||
|
||||
$responseData = $result;
|
||||
unset($responseData['refresh_token']);
|
||||
|
||||
Response::json([
|
||||
'success' => true,
|
||||
'data' => ['user_id' => $userId, 'email' => $email],
|
||||
'message' => 'تم التحقق بنجاح'
|
||||
'data' => $responseData,
|
||||
'message' => 'تم التحقق وتأسيس الجلسة بنجاح'
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -265,4 +251,41 @@ final class AuthController
|
||||
|
||||
Response::json(['success' => true, 'message' => 'تم تعطيل التحقق الثنائي']);
|
||||
}
|
||||
|
||||
private function setAuthCookies(array $result): void
|
||||
{
|
||||
$cookieDomain = $_SERVER['HTTP_HOST'] ?? '';
|
||||
$secure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
|
||||
|
||||
// 1. Refresh Token (HttpOnly, scoped to /refresh)
|
||||
setcookie('refresh_token', $result['refresh_token'] ?? '', [
|
||||
'expires' => time() + (60 * 60 * 24 * 7), // 7 days
|
||||
'path' => '/api/v1/auth/refresh',
|
||||
'domain' => $cookieDomain,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => $secure
|
||||
]);
|
||||
|
||||
// 2. Access Token (HttpOnly, scoped to /)
|
||||
setcookie('access_token', $result['access_token'] ?? '', [
|
||||
'expires' => time() + (60 * 15), // 15 mins
|
||||
'path' => '/',
|
||||
'domain' => $cookieDomain,
|
||||
'httponly' => true,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => $secure
|
||||
]);
|
||||
|
||||
// 3. CSRF Token (Readable by JS)
|
||||
$csrfToken = bin2hex(random_bytes(32));
|
||||
setcookie('csrf_token', $csrfToken, [
|
||||
'expires' => time() + (60 * 15),
|
||||
'path' => '/',
|
||||
'domain' => $cookieDomain,
|
||||
'httponly' => false,
|
||||
'samesite' => 'Strict',
|
||||
'secure' => $secure
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user