Skip to content

Commit 35414d7

Browse files
committed
PHP API using JWT
0 parents  commit 35414d7

24 files changed

+1676
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/vendor/

auth/.htaccess

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
RewriteEngine on
2+
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

auth/classes/auth.php

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<?php
2+
3+
$my_country_timezone = 'Europe/Tirane';
4+
5+
date_default_timezone_set($my_country_timezone);
6+
7+
include '../vendor/autoload.php';
8+
include '../controllers/helpers/date_time.php';
9+
10+
11+
use \Firebase\JWT\JWT;
12+
use \Firebase\JWT\Key;
13+
14+
15+
class Auth extends DateTimeLocal
16+
{
17+
private $privateKey = 'My_Private_Key';
18+
19+
public function jwt_encode($payload, string $sslcode = 'HS256')
20+
{
21+
$json_web_token = JWT::encode($payload, $this->privateKey, $sslcode);
22+
23+
return $json_web_token;
24+
}
25+
26+
public function jwt_decode($payload, string $sslcode = 'HS256')
27+
{
28+
$jwt_user_data = JWT::decode($payload, new Key($this->privateKey, $sslcode));
29+
30+
return $jwt_user_data;
31+
}
32+
33+
public function get_user_data()
34+
{
35+
$headers = getallheaders();
36+
$user_data = $headers['Authentication'];
37+
echo $user_data;
38+
}
39+
40+
public function generate_token(int $user_id, string $user_role)
41+
{
42+
$expire = $this->set_expire_time(30);
43+
$expiration_time = $expire;
44+
45+
// jwt payload
46+
$payload = [
47+
'id' => $user_id,
48+
'user_role' => $user_role,
49+
"exp" => $expiration_time
50+
];
51+
52+
// Encode the token payload with JWT secret key
53+
$token = $this->jwt_encode($payload, 'HS256');
54+
55+
return $token;
56+
}
57+
}
58+
59+
$auth = new Auth();

auth/delete.php

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
header('Access-Control-Allow-Origin: *');
4+
header('Access-Control-Allow-Method: POST');
5+
header('Content-Type: application/json; Charset=UTF-8');
6+
7+
require '../classes/crud_actions.php';
8+
include '../auth/classes/auth.php';
9+
10+
$obj = new CRUD();
11+
12+
if ($_SERVER["REQUEST_METHOD"] !== "POST") {
13+
echo json_encode([
14+
'status' => 0,
15+
'message' => 'Access Denied!'
16+
]);
17+
18+
die();
19+
}
20+
21+
$data = json_decode(file_get_contents("php://input"));
22+
23+
$id = null;
24+
if (!$data && isset($_GET['id'])) {
25+
$id = $_GET['id'];
26+
} else {
27+
$id = $data->id;
28+
}
29+
30+
if ($id === null) die('Something went wrong while trying to delete theres no id!');
31+
32+
$headers = getallheaders();
33+
34+
$json_web_token = $headers['Authorization'] ?? [];
35+
// echo $json_web_token;
36+
if (!$headers || !$json_web_token) {
37+
http_response_code(500);
38+
echo json_encode(['status' => 0, 'message' => 'Server error!']);
39+
die();
40+
}
41+
42+
// check if logged user/person is admin
43+
$user_data = $auth->jwt_decode($json_web_token, 'HS256');
44+
$data = $user_data->data;
45+
$user_role = $data->user_role;
46+
47+
// check if the user exist before deleting it
48+
$user_data = $obj->userExists($id, '', true);
49+
50+
if ($user_data && $user_role !== 'admin') {
51+
http_response_code(403);
52+
53+
echo json_encode([
54+
'status' => 0,
55+
'message' => 'You have no authorization to this particular action!'
56+
]);
57+
58+
die();
59+
}
60+
61+
62+
if (!$user_data) {
63+
http_response_code(500);
64+
65+
$resMsg = empty($user_data) > 0 ? 'User does not exists!' : 'User has been deleted! User not founded.';
66+
67+
echo json_encode([
68+
'status' => 0,
69+
'message' => $resMsg
70+
]);
71+
72+
die();
73+
}
74+
75+
76+
// delete user
77+
$obj->delete("users", "id = {$id}");
78+
$result = $obj->getResult();
79+
80+
if (!$result[2]['delete']) {
81+
echo json_encode([
82+
'status' => 0,
83+
'message' => 'Something went wrong! Server problem.'
84+
]);
85+
86+
exit();
87+
}
88+
89+
90+
$successMsg = 'User ' . ($id ? ':' . $id . ', ' : '') . 'deleted successfully!';
91+
echo json_encode([
92+
'status' => 1,
93+
'message' => $successMsg
94+
]);

auth/error/403.html

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<title>403 Not Authorized!</title>
9+
</head>
10+
11+
<body>
12+
<p>No premission / Access Denied!</p> <br />
13+
<a href="../login-user.php">Login to Continue.</a> <br />
14+
<a href="../../products/all-products.php">Homepage</a>
15+
</body>
16+
17+
</html>

auth/login.php

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
header('Access-Control-Allow-Origin: *');
4+
header('Access-Control-Allow-Method: POST');
5+
header('Content-Type: application/json; Charset=UTF-8');
6+
7+
require '../classes/crud_actions.php';
8+
include '../auth/classes/auth.php';
9+
10+
$obj = new CRUD();
11+
12+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
13+
echo json_encode([
14+
'status' => 0,
15+
'message' => 'Access Denied',
16+
]);
17+
18+
unset($_COOKIE['jwt_token']);
19+
20+
die();
21+
}
22+
23+
$data = json_decode(file_get_contents("php://input"), true);
24+
25+
$uid = htmlentities($data['uid'] ?? $data['username']);
26+
27+
$username = '';
28+
$email = '';
29+
30+
if (gettype($uid) === 'string') {
31+
if (!str_contains($uid, '@')) {
32+
$username = $uid;
33+
} else {
34+
$email = $uid;
35+
}
36+
}
37+
38+
$password = htmlentities($data['password']);
39+
40+
if (!$obj->userExists($username, $email)) {
41+
http_response_code(500);
42+
43+
echo json_encode([
44+
'status' => 0,
45+
'message' => 'User does not Exists!',
46+
]);
47+
48+
die();
49+
}
50+
51+
$obj->select('users', '*', null, "username='$username' OR email='$email'", null, null);
52+
$data = $obj->userExists($username, $email, true);
53+
54+
// user login token time-left to expire
55+
$exp_login_token_time = $datetime->set_expire_time(60);
56+
$login_token_time_to_exp = $exp_login_token_time['time'];
57+
$login_token_time_tostr = $exp_login_token_time['time_to_str'];
58+
59+
# Only when debugging: echo $login_token_time_tostr;
60+
61+
$id = $data['id'] ?? '';
62+
$name = $data['name'];
63+
$surname = $data['surname'];
64+
$username = $data['username'] ?? '';
65+
$email = $data['email'] ?? '';
66+
$user_password = $data['password'] ?? '';
67+
$user_role = $data['role'] ?? '';
68+
69+
if (!password_verify($password, $user_password)) {
70+
echo json_encode([
71+
'status' => 0,
72+
'message' => 'Invalid Credentials',
73+
]);
74+
75+
exit();
76+
}
77+
78+
$payload = [
79+
'iss' => 'localhost',
80+
'aud' => 'localhost',
81+
'exp' => $login_token_time_to_exp, // 30min
82+
'data' => [
83+
'id' => $id,
84+
'name' => $name,
85+
'surname' => $surname,
86+
'username' => $username,
87+
'email' => $email,
88+
'user_role' => $user_role
89+
]
90+
];
91+
92+
93+
$json_web_token = $auth->jwt_encode($payload, 'HS256');
94+
95+
$cookie_params = [
96+
'expires' => $login_token_time_to_exp,
97+
'path' => '/',
98+
'secure' => true,
99+
// 'httponly' => true,
100+
'samesite' => 'Strict'
101+
];
102+
103+
echo json_encode([
104+
'status' => 1,
105+
'user' => [
106+
'name' => $name,
107+
'surname' => $surname
108+
],
109+
// 'jwt' => $json_web_token, // only if you want to manipulate token in front_end
110+
'message' => 'Login Successfully!',
111+
]);
112+
113+
if (isset($_COOKIE['jwt_token']) && !empty($_COOKIE['jwt_token'])) exit();
114+
115+
setcookie('jwt_token', $json_web_token, $cookie_params);
116+
117+
if ($user_role === 'admin') {
118+
setcookie('user_role', $user_role, [
119+
'expires' => $login_token_time_to_exp,
120+
'path' => '/',
121+
'secure' => true,
122+
'httponly' => true,
123+
'samesite' => 'Strict'
124+
]);
125+
}

auth/logout.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
header('Access-Control-Allow-Origin: *');
4+
header('Access-Control-Allow-Method: POST');
5+
header('Content-Type: application/json; Charset=UTF-8');
6+
7+
require '../auth/classes/auth.php';
8+
9+
// Handle logout request
10+
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
11+
http_response_code(500);
12+
echo json_encode([
13+
'status' => 0,
14+
'message' => 'Access Denied'
15+
]);
16+
exit();
17+
}
18+
19+
20+
$data = json_decode(file_get_contents("php://input", true));
21+
22+
// Retrieve JWT token from Authorization header
23+
$auth_header = $_SERVER['HTTP_AUTHORIZATION'];
24+
$token = $auth_header;
25+
26+
if (str_contains($token, 'Bearer')) {
27+
$token = str_replace('Bearer ', '', $token);
28+
}
29+
30+
if (!$token) {
31+
// Return response indicating no JWT token was present
32+
http_response_code(400);
33+
header('Content-Type: application/json');
34+
echo json_encode(array('message' => 'No JWT token present'));
35+
36+
die();
37+
}
38+
39+
40+
// Decode JWT token
41+
$payload = $auth->jwt_decode($token);
42+
43+
// Set expiration time to a date in the past
44+
$payload->exp = strtotime('-1 day');
45+
46+
// Encode modified payload back into a new JWT token
47+
$new_token = $auth->jwt_encode((array) $payload);
48+
49+
// Return response indicating logout was successful
50+
header('Content-Type: application/json');
51+
52+
53+
$cookie_params = [
54+
'expires' => time() + 1,
55+
'path' => '/',
56+
'secure' => true,
57+
// 'httponly' => true,
58+
'samesite' => 'Strict'
59+
];
60+
61+
setcookie('jwt_token', '', $cookie_params);
62+
unset($_COOKIE['jwt_token']);
63+
setcookie('user_role', '', $cookie_params);
64+
65+
if (isset($_COOKIE['jwt_token'])) {
66+
die();
67+
}
68+
69+
echo json_encode(['status' => 1, 'message' => 'You have been, Logged Out!']);

0 commit comments

Comments
 (0)