2025-06-26 14:09:25 +07:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Controllers;
|
|
|
|
|
|
|
|
|
|
use CodeIgniter\API\ResponseTrait;
|
|
|
|
|
use CodeIgniter\Controller;
|
2025-09-03 22:45:57 +07:00
|
|
|
|
|
|
|
|
use Firebase\JWT\JWT;
|
|
|
|
|
use Firebase\JWT\Key;
|
|
|
|
|
use Firebase\JWT\ExpiredException;
|
|
|
|
|
use Firebase\JWT\SignatureInvalidException;
|
|
|
|
|
use Firebase\JWT\BeforeValidException;
|
2025-09-03 15:36:55 +07:00
|
|
|
use CodeIgniter\Cookie\Cookie;
|
2025-06-26 14:09:25 +07:00
|
|
|
|
|
|
|
|
class Auth extends Controller {
|
|
|
|
|
use ResponseTrait;
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// ok
|
2025-06-26 14:09:25 +07:00
|
|
|
public function __construct() {
|
|
|
|
|
$this->db = \Config\Database::connect();
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// ok
|
|
|
|
|
public function checkAuth() {
|
|
|
|
|
$token = $this->request->getCookie('token');
|
|
|
|
|
$key = getenv('JWT_SECRET');
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// Jika token FE tidak ada langsung kabarkan failed
|
|
|
|
|
if (!$token) {
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'failed',
|
|
|
|
|
'message' => 'No token found'
|
|
|
|
|
], 401);
|
|
|
|
|
}
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
try {
|
|
|
|
|
// Decode Token dengan Key yg ada di .env
|
|
|
|
|
$decodedPayload = JWT::decode($token, new Key($key, 'HS256'));
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'success',
|
|
|
|
|
'message' => 'Authenticated',
|
|
|
|
|
'data' => $decodedPayload
|
|
|
|
|
], 200);
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
} catch (ExpiredException $e) {
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'failed',
|
|
|
|
|
'message' => 'Token expired',
|
|
|
|
|
'data' => []
|
|
|
|
|
], 401);
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
} catch (SignatureInvalidException $e) {
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'failed',
|
|
|
|
|
'message' => 'Invalid token signature',
|
|
|
|
|
'data' => []
|
|
|
|
|
], 401);
|
|
|
|
|
|
|
|
|
|
} catch (BeforeValidException $e) {
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'failed',
|
|
|
|
|
'message' => 'Token not valid yet',
|
|
|
|
|
'data' => []
|
|
|
|
|
], 401);
|
|
|
|
|
|
|
|
|
|
} catch (\Exception $e) {
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'failed',
|
|
|
|
|
'message' => 'Invalid token: ' . $e->getMessage(),
|
|
|
|
|
'data' => []
|
|
|
|
|
], 401);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ok
|
2025-12-30 09:10:50 +07:00
|
|
|
// public function login() {
|
|
|
|
|
|
|
|
|
|
// // Ambil dari JSON Form dan Key .env
|
|
|
|
|
// $username = $this->request->getVar('username');
|
|
|
|
|
// $password = $this->request->getVar('password');
|
|
|
|
|
// $key = getenv('JWT_SECRET');
|
|
|
|
|
|
|
|
|
|
// if (!$username) {
|
|
|
|
|
// return $this->fail('Username required.', 400);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// $sql = "SELECT * FROM users WHERE username=" . $this->db->escape($username);
|
|
|
|
|
// $query = $this->db->query($sql);
|
|
|
|
|
// $row = $query->getResultArray();
|
|
|
|
|
|
|
|
|
|
// if (!$row) { return $this->fail('User not found.', 401); }
|
|
|
|
|
// $row = $row[0];
|
|
|
|
|
// if (!password_verify($password, $row['password'])) {
|
|
|
|
|
// return $this->fail('Invalid password.', 401);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // Buat JWT payload
|
|
|
|
|
// $exp = time() + 864000;
|
|
|
|
|
// $payload = [
|
|
|
|
|
// 'userid' => $row['id'],
|
|
|
|
|
// 'roleid' => $row['role_id'],
|
|
|
|
|
// 'username' => $row['username'],
|
|
|
|
|
// 'exp' => $exp
|
|
|
|
|
// ];
|
|
|
|
|
|
|
|
|
|
// try {
|
|
|
|
|
// // Melakukan Hash terhadap Payload dengan Kunci .env menggunakan Algortima HMAC + SHA-256
|
|
|
|
|
// $jwt = JWT::encode($payload, $key, 'HS256');
|
|
|
|
|
// } catch (Exception $e) {
|
|
|
|
|
// return $this->fail('Error generating JWT: ' . $e->getMessage(), 500);
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
// // Kirim Respon ke HttpOnly yg akan disimpan di browser dan tidak akan dapat diakses oleh siapapun
|
|
|
|
|
// // $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
|
|
|
|
|
// $this->response->setCookie([
|
|
|
|
|
// // 'name' => 'token', // nama token
|
|
|
|
|
// // 'value' => $jwt, // value dari jwt yg sudah di hash
|
|
|
|
|
// // 'expire' => 864000, // 10 hari
|
|
|
|
|
// // 'path' => '/', // valid untuk semua path
|
|
|
|
|
// // 'secure' => $isSecure, // true for HTTPS, false for HTTP (localhost)
|
|
|
|
|
// // 'httponly' => true, // dipakai agar cookie berikut tidak dapat diakses oleh javascript
|
|
|
|
|
// // 'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
|
|
|
|
|
// ]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // Response tanpa token di body
|
|
|
|
|
// return $this->respond([
|
|
|
|
|
// 'status' => 'success',
|
|
|
|
|
// 'code' => 200,
|
|
|
|
|
// 'message' => 'Login successful'
|
|
|
|
|
// ], 200);
|
|
|
|
|
// }
|
|
|
|
|
public function login() {
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// Ambil dari JSON Form dan Key .env
|
2025-06-26 14:09:25 +07:00
|
|
|
$username = $this->request->getVar('username');
|
|
|
|
|
$password = $this->request->getVar('password');
|
|
|
|
|
$key = getenv('JWT_SECRET');
|
|
|
|
|
|
|
|
|
|
if (!$username) {
|
|
|
|
|
return $this->fail('Username required.', 400);
|
|
|
|
|
}
|
2025-09-03 15:36:55 +07:00
|
|
|
|
|
|
|
|
$sql = "SELECT * FROM users WHERE username=" . $this->db->escape($username);
|
2025-06-26 14:09:25 +07:00
|
|
|
$query = $this->db->query($sql);
|
2025-09-23 09:25:13 +07:00
|
|
|
$row = $query->getResultArray();
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-23 09:25:13 +07:00
|
|
|
if (!$row) { return $this->fail('User not found.', 401); }
|
|
|
|
|
$row = $row[0];
|
2025-06-26 14:09:25 +07:00
|
|
|
if (!password_verify($password, $row['password'])) {
|
|
|
|
|
return $this->fail('Invalid password.', 401);
|
|
|
|
|
}
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// Buat JWT payload
|
2025-09-09 09:16:35 +07:00
|
|
|
$exp = time() + 864000;
|
2025-06-26 14:09:25 +07:00
|
|
|
$payload = [
|
2025-09-03 15:36:55 +07:00
|
|
|
'userid' => $row['id'],
|
2025-09-08 13:33:48 +07:00
|
|
|
'roleid' => $row['role_id'],
|
2025-06-26 14:09:25 +07:00
|
|
|
'username' => $row['username'],
|
2025-09-08 13:39:12 +07:00
|
|
|
'exp' => $exp
|
2025-06-26 14:09:25 +07:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
try {
|
2025-09-03 22:45:57 +07:00
|
|
|
// Melakukan Hash terhadap Payload dengan Kunci .env menggunakan Algortima HMAC + SHA-256
|
2025-06-26 14:09:25 +07:00
|
|
|
$jwt = JWT::encode($payload, $key, 'HS256');
|
|
|
|
|
} catch (Exception $e) {
|
|
|
|
|
return $this->fail('Error generating JWT: ' . $e->getMessage(), 500);
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// Kirim Respon ke HttpOnly yg akan disimpan di browser dan tidak akan dapat diakses oleh siapapun
|
2025-09-03 15:36:55 +07:00
|
|
|
$this->response->setCookie([
|
2025-12-30 09:10:50 +07:00
|
|
|
'name' => 'token', // nama token
|
|
|
|
|
'value' => $jwt, // value dari jwt yg sudah di hash
|
|
|
|
|
'expire' => 864000, // 10 hari
|
|
|
|
|
'path' => '/', // valid untuk semua path
|
|
|
|
|
'secure' => true, // set true kalau sudah HTTPS
|
|
|
|
|
'httponly' => true, // dipakai agar cookie berikut tidak dapat diakses oleh javascript
|
|
|
|
|
'samesite' => Cookie::SAMESITE_NONE
|
2025-09-03 15:36:55 +07:00
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Response tanpa token di body
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'success',
|
2025-09-08 13:33:48 +07:00
|
|
|
'code' => 200,
|
2025-09-03 15:36:55 +07:00
|
|
|
'message' => 'Login successful'
|
2025-09-03 22:45:57 +07:00
|
|
|
], 200);
|
2025-06-26 14:09:25 +07:00
|
|
|
}
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// ok
|
2025-12-30 09:12:32 +07:00
|
|
|
// public function logout() {
|
|
|
|
|
// // Definisikan ini pada cookies browser, harus sama dengan cookies login
|
|
|
|
|
// // $isSecure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on';
|
|
|
|
|
// return $this->response->setCookie([
|
|
|
|
|
// 'name' => 'token',
|
|
|
|
|
// 'value' => '',
|
|
|
|
|
// 'expire' => time() - 3600,
|
|
|
|
|
// 'path' => '/',
|
|
|
|
|
// 'secure' => $isSecure,
|
|
|
|
|
// 'httponly' => true,
|
|
|
|
|
// 'samesite' => $isSecure ? Cookie::SAMESITE_NONE : Cookie::SAMESITE_LAX
|
|
|
|
|
|
|
|
|
|
// ])->setJSON([
|
|
|
|
|
// 'status' => 'success',
|
|
|
|
|
// 'code' => 200,
|
|
|
|
|
// 'message' => 'Logout successful'
|
|
|
|
|
// ], 200);
|
|
|
|
|
// }
|
2025-09-03 22:45:57 +07:00
|
|
|
public function logout() {
|
|
|
|
|
// Definisikan ini pada cookies browser, harus sama dengan cookies login
|
|
|
|
|
return $this->response->setCookie([
|
|
|
|
|
'name' => 'token',
|
|
|
|
|
'value' => '',
|
|
|
|
|
'expire' => time() - 3600,
|
|
|
|
|
'path' => '/',
|
2025-12-30 09:12:32 +07:00
|
|
|
'secure' => true,
|
2025-09-03 22:45:57 +07:00
|
|
|
'httponly' => true,
|
2025-12-30 09:12:32 +07:00
|
|
|
'samesite' => Cookie::SAMESITE_NONE
|
2025-06-26 14:09:25 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
])->setJSON([
|
2025-09-08 13:33:48 +07:00
|
|
|
'status' => 'success',
|
|
|
|
|
'code' => 200,
|
2025-09-03 22:45:57 +07:00
|
|
|
'message' => 'Logout successful'
|
|
|
|
|
], 200);
|
2025-06-26 14:09:25 +07:00
|
|
|
}
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// ok
|
2025-06-26 14:09:25 +07:00
|
|
|
public function register() {
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-08 13:33:48 +07:00
|
|
|
$username = strtolower($this->request->getJsonVar('username'));
|
2025-06-26 14:09:25 +07:00
|
|
|
$password = $this->request->getJsonVar('password');
|
|
|
|
|
|
2025-09-08 13:33:48 +07:00
|
|
|
// Validasi Awal Dari BE
|
2025-09-03 22:45:57 +07:00
|
|
|
if (empty($username) || empty($password)) {
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'failed',
|
2025-09-08 13:33:48 +07:00
|
|
|
'code' => 400,
|
2025-09-03 22:45:57 +07:00
|
|
|
'message' => 'Username and password are required'
|
|
|
|
|
], 400); // Gunakan 400 Bad Request
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-08 13:33:48 +07:00
|
|
|
// Cek Duplikasi Username
|
|
|
|
|
$exists = $this->db->query("SELECT id FROM users WHERE username = ?", [$username])->getRow();
|
|
|
|
|
if ($exists) {
|
|
|
|
|
return $this->respond(['status' => 'failed', 'code'=>409,'message' => 'Username already exists'], 409);
|
|
|
|
|
}
|
2025-09-03 23:05:06 +07:00
|
|
|
|
2025-09-08 13:33:48 +07:00
|
|
|
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
|
|
|
|
|
|
|
|
|
|
// Mulai transaksi Insert
|
|
|
|
|
$this->db->transStart();
|
|
|
|
|
$this->db->query(
|
|
|
|
|
"INSERT INTO users(username, password, role_id) VALUES(?, ?, ?)",
|
|
|
|
|
[$username, $hashedPassword, 1]
|
|
|
|
|
);
|
|
|
|
|
$this->db->transComplete();
|
|
|
|
|
|
|
|
|
|
// Cek status transaksi
|
|
|
|
|
if ($this->db->transStatus() === false) {
|
2025-09-03 23:02:27 +07:00
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'error',
|
2025-09-08 13:33:48 +07:00
|
|
|
'code' => 500,
|
2025-09-03 23:02:27 +07:00
|
|
|
'message' => 'Failed to create user. Please try again later.'
|
2025-09-08 13:33:48 +07:00
|
|
|
], 500);
|
2025-09-03 23:02:27 +07:00
|
|
|
}
|
2025-09-08 13:33:48 +07:00
|
|
|
|
|
|
|
|
// Respon sukses jika kueri berhasil
|
|
|
|
|
return $this->respond([
|
|
|
|
|
'status' => 'success',
|
|
|
|
|
'code' => 201,
|
|
|
|
|
'message' => 'User ' . $username . ' successfully created.'
|
|
|
|
|
], 201);
|
|
|
|
|
|
2025-06-26 14:09:25 +07:00
|
|
|
}
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// public function change_pass() {
|
|
|
|
|
// $db = \Config\Database::connect();
|
|
|
|
|
// $username = $this->request->getJsonVar('username');
|
|
|
|
|
// $password = $this->request->getJsonVar('password');
|
|
|
|
|
// $password = password_hash($password, PASSWORD_DEFAULT);
|
2025-06-26 14:09:25 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// $master = $this->request->getJsonVar('master');
|
|
|
|
|
// $masterkey = getenv('masterkey');
|
2025-06-26 14:09:25 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// if($master != $masterkey) {
|
|
|
|
|
// return $this->fail('Invalid master key.', 401);
|
|
|
|
|
// }
|
2025-06-26 14:09:25 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
// $sql = "update users set password='$password' where username='$username'";
|
|
|
|
|
// $query = $db->query($sql);
|
|
|
|
|
// $response = [
|
|
|
|
|
// 'message' => "Password Changed for $username"
|
|
|
|
|
// ];
|
|
|
|
|
// return $this->respond($response);
|
|
|
|
|
// }
|
2025-09-03 15:36:55 +07:00
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
public function coba() {
|
2025-09-04 09:42:30 +07:00
|
|
|
|
|
|
|
|
$token = $this->request->getCookie('token');
|
|
|
|
|
$key = getenv('JWT_SECRET');
|
|
|
|
|
|
|
|
|
|
// Decode Token dengan Key yg ada di .env
|
|
|
|
|
$decodedPayload = JWT::decode($token, new Key($key, 'HS256'));
|
|
|
|
|
|
2025-09-03 22:45:57 +07:00
|
|
|
return $this->respond([
|
2025-09-04 09:42:30 +07:00
|
|
|
'status' => 'success',
|
|
|
|
|
'message' => 'Authenticated',
|
|
|
|
|
'data' => $decodedPayload
|
|
|
|
|
], 200);
|
2025-09-03 22:45:57 +07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|