Files
kngil_home/kngil/bbs/login_sms.php
2026-01-30 17:20:52 +09:00

212 lines
5.5 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* Sentinel SMS 매직링크 로그인 (PHP)
* - system: kngil
* - secret_key: MY_SECRET_KEY
*/
session_start();
require_once $_SERVER['DOCUMENT_ROOT'].'/kngil/bbs/db_conn.php';
header('Content-Type: application/json; charset=utf-8');
/* =========================
설정값
========================= */
$AUTH_SERVER = 'http://61.98.205.242:8075';
$SYSTEM = 'kngil';
$SECRET_KEY = '9f3b2e7a0a4f1f25c41c8c2367d04d54a89a2a5b2b189d63a99a0b874db4b27f';
/* =========================
입력 처리
========================= */
$input = json_decode(file_get_contents('php://input'), true) ?? [];
$mode = $_GET['mode'] ?? $input['mode'] ?? '';
/* =========================
JWT 생성 (HS256)
========================= */
function base64url_encode($data) {
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
function create_jwt($payload, $secret) {
$header = ['alg' => 'HS256', 'typ' => 'JWT'];
$segments = [];
$segments[] = base64url_encode(json_encode($header));
$segments[] = base64url_encode(json_encode($payload));
$signing_input = implode('.', $segments);
$signature = hash_hmac('sha256', $signing_input, $secret, true);
$segments[] = base64url_encode($signature);
return implode('.', $segments);
}
/* =========================
cURL JSON 요청
========================= */
function curl_json($url, $method = 'GET', $headers = [], $body = null) {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => $method,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POSTFIELDS => $body,
CURLOPT_TIMEOUT => 10
]);
$response = curl_exec($ch);
$err = curl_error($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($err) {
throw new Exception($err);
}
return [$code, $response];
}
try {
/* =========================
1⃣ 매직링크 발급 요청
========================= */
if ($mode === 'request') {
$rawPhone = $input['phone'] ?? '';
$phone = preg_replace('/[^0-9]/', '', $rawPhone);
if (!$phone) {
echo json_encode([
'status' => 'error',
'message' => '휴대폰 번호를 입력하세요.'
]);
exit;
}
// JWT payload (3분 유효)
$payload = [
'system' => $SYSTEM,
'iat' => time(),
'exp' => time() + 180
];
$jwt = create_jwt($payload, $SECRET_KEY);
[$code, $res] = curl_json(
$AUTH_SERVER . '/auth/sentinel',
'POST',
[
'Authorization: Bearer ' . $jwt,
'Content-Type: application/json'
],
json_encode([
'phoneNumber' => $phone
])
);
$result = json_decode($res, true);
if (empty($result['token'])) {
throw new Exception('Sentinel token 발급 실패');
}
// ✅ token 반드시 저장
$_SESSION['sms_login'] = [
'phone' => $phone,
'token' => $result['token']
];
echo json_encode([
'status' => 'success'
]);
exit;
}
/* =========================
2⃣ 매직링크 상태 확인 → 자동 로그인
========================= */
if ($mode === 'status') {
if (
empty($_SESSION['sms_login']['token']) ||
empty($_SESSION['sms_login']['phone'])
) {
echo json_encode(['status' => 'pending']);
exit;
}
$token = $_SESSION['sms_login']['token'];
$phone = $_SESSION['sms_login']['phone'];
$payload = [
'system' => $SYSTEM,
'iat' => time(),
'exp' => time() + 180
];
$jwt = create_jwt($payload, $SECRET_KEY);
[$code, $res] = curl_json(
$AUTH_SERVER . '/auth/status?token=' . $token,
'GET',
[
'Authorization: Bearer ' . $jwt
]
);
$data = json_decode($res, true);
// 🔴 인증 완료 시 로그인 처리
if (!empty($data['loggedIn'])) {
$stmt = $pdo->prepare("
SELECT
member_id,
user_id,
user_nm,
auth_bc
FROM kngil.users
WHERE REPLACE(tel_no, '-', '') = :phone
AND use_yn = 'Y'
LIMIT 1
");
$stmt->execute([':phone' => $phone]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$user) {
throw new Exception('해당 번호로 등록된 사용자 없음');
}
// ✅ 기존 PW 로그인과 동일
$_SESSION['login'] = [
'member_id' => $user['member_id'],
'user_id' => $user['user_id'],
'user_nm' => $user['user_nm'],
'auth_bc' => $user['auth_bc']
];
unset($_SESSION['sms_login']);
echo json_encode([
'status' => 'success',
'message' => '자동 로그인 완료'
], JSON_UNESCAPED_UNICODE);
exit;
}
echo json_encode(['status' => 'pending']);
exit;
}
} catch (Exception $e) {
echo json_encode([
'error' => true,
'message' => $e->getMessage()
], JSON_UNESCAPED_UNICODE);
}