setClientId($clientID);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($redirectUri);
// OAuth scopes
$client->addScope('openid');
$client->addScope('email');
$client->addScope('profile');
// Ζητάμε offline access όπου χρειάζεται
$client->setAccessType('online');
// Για να παίρνουμε πάντα consent όταν χρειάζεται
$client->setPrompt('select_account');
// ============================================================
// GOOGLE CALLBACK
// ============================================================
if (isset($_GET['code'])) {
// --------------------------------------------------------
// Έλεγχος OAuth state
// --------------------------------------------------------
if (
!isset($_GET['state']) ||
!isset($_SESSION['google_oauth_state']) ||
!hash_equals($_SESSION['google_oauth_state'], $_GET['state'])
) {
die('Μη έγκυρο OAuth state.');
}
unset($_SESSION['google_oauth_state']);
// --------------------------------------------------------
// Ανταλλαγή authorization code με access token
// --------------------------------------------------------
try {
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
} catch (Exception $e) {
die(
'Σφάλμα κατά τη σύνδεση με Google: ' .
htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8')
);
}
if (isset($token['error'])) {
$errorDescription = $token['error_description'] ?? $token['error'];
die(
'Google OAuth Error: ' .
htmlspecialchars($errorDescription, ENT_QUOTES, 'UTF-8')
);
}
if (!isset($token['access_token'])) {
die('Δεν ελήφθη access token από τη Google.');
}
$client->setAccessToken($token['access_token']);
// --------------------------------------------------------
// Λήψη στοιχείων χρήστη από Google
// --------------------------------------------------------
try {
$google_oauth = new Google_Service_Oauth2($client);
$google_account_info = $google_oauth->userinfo->get();
} catch (Exception $e) {
die(
'Αδυναμία λήψης στοιχείων από Google: ' .
htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8')
);
}
// --------------------------------------------------------
// User information
// --------------------------------------------------------
$email = trim((string) $google_account_info->email);
$first_name = trim((string) ($google_account_info->givenName ?? ''));
$last_name = trim((string) ($google_account_info->familyName ?? ''));
if ($email === '') {
die('Η Google δεν επέστρεψε email για τον χρήστη.');
}
// ========================================================
// SEARCH USER IN DATABASE
// ========================================================
try {
$stmt = $pdo->prepare(
"SELECT *
FROM users
WHERE username = ? OR email = ?
LIMIT 1"
);
$stmt->execute([$email, $email]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die(
'Σφάλμα βάσης δεδομένων: ' .
htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8')
);
}
// ========================================================
// EXISTING USER
// ========================================================
if ($user) {
// Προαιρετικά ενημερώνουμε όνομα/επώνυμο
// αν υπάρχουν διαθέσιμα από Google.
if (empty($user['first_name']) && $first_name !== '') {
$update = $pdo->prepare(
"UPDATE users
SET first_name = ?
WHERE id = ?"
);
$update->execute([$first_name, $user['id']]);
$user['first_name'] = $first_name;
}
if (empty($user['last_name']) && $last_name !== '') {
$update = $pdo->prepare(
"UPDATE users
SET last_name = ?
WHERE id = ?"
);
$update->execute([$last_name, $user['id']]);
$user['last_name'] = $last_name;
}
// ----------------------------------------------------
// Login
// ----------------------------------------------------
session_regenerate_id(true);
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
$_SESSION['role_id'] = $user['role_id'];
$_SESSION['first_name'] = $user['first_name'] ?? '';
$_SESSION['is_seller'] = $user['is_seller'] ?? 0;
}
// ========================================================
// NEW USER
// ========================================================
else {
// Τυχαίος password επειδή ο χρήστης θα κάνει login μέσω Google.
$random_password = password_hash(
bin2hex(random_bytes(32)),
PASSWORD_DEFAULT
);
// 3 = Απλός χρήστης / Πελάτης
// 2 = Seller
// 1 = Admin
$role_id = 3;
try {
$insert = $pdo->prepare(
"INSERT INTO users
(
username,
email,
password,
first_name,
last_name,
role_id
)
VALUES (?, ?, ?, ?, ?, ?)"
);
$insert->execute([
$email,
$email,
$random_password,
$first_name,
$last_name,
$role_id
]);
$new_user_id = $pdo->lastInsertId();
} catch (PDOException $e) {
die(
'Σφάλμα κατά την αυτόματη εγγραφή του χρήστη: ' .
htmlspecialchars($e->getMessage(), ENT_QUOTES, 'UTF-8')
);
}
// ----------------------------------------------------
// Login νέου χρήστη
// ----------------------------------------------------
session_regenerate_id(true);
$_SESSION['user_id'] = $new_user_id;
$_SESSION['username'] = $email;
$_SESSION['role_id'] = $role_id;
$_SESSION['first_name'] = $first_name;
$_SESSION['is_seller'] = 0;
}
// ========================================================
// SUCCESS
// ========================================================
header('Location: index.php');
exit;
}
// ============================================================
// INITIAL REQUEST - REDIRECT TO GOOGLE
// ============================================================
else {
// Δημιουργία τυχαίου state για προστασία από CSRF
$state = bin2hex(random_bytes(32));
$_SESSION['google_oauth_state'] = $state;
$client->setState($state);
// Δημιουργία Google authorization URL
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
exit;
}