-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAuth.php
133 lines (113 loc) · 3.81 KB
/
Auth.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Firebase\JWT\ExpiredException;
require_once('./vendor/autoload.php');
$env = parse_ini_file('.env');
function logger($message, $logFile = "debug.log") {
$message .= PHP_EOL;
return file_put_contents($logFile, $message, FILE_APPEND);
}
class Auth {
private $service;
private $date;
private $payload_base;
public function __construct($service) {
global $env;
$this->service = $service;
$this->date = new DateTimeImmutable();
$this->payload_base = [
'iat' => $this->date->getTimestamp(),
'iss' => $env['domain'],
'nbf' => $this->date->getTimestamp()
];
}
private function expiration($shift) {
return $this->date->modify($shift)->getTimestamp();
}
private function refresh_token($user) {
global $env;
$refresh_token = JWT::encode(
array_merge([
'exp' => $this->expiration('+24 hours'),
'username' => $user
], $this->payload_base),
$env['refresh_token_secret'],
'HS512'
);
// number of mili seconds
$token_duration = time() + (intval($env['refresh_token_duration']) * 1000);
setcookie($env['refresh_cookie'], $refresh_token, $token_duration, "/", $env['domain'], 0, 1);
}
private function generate_access_token($user) {
global $env;
$access_token = JWT::encode(
array_merge([
'exp' => $this->expiration('+1 minutes'),
'username' => $user
], $this->payload_base),
$env['access_token_secret'],
'HS512'
);
return $access_token;
}
public function refresh() {
global $env;
if (!isset($_COOKIE[$env['refresh_cookie']])) {
throw new Exception("Refresh token not found!");
}
$jwt = $_COOKIE[$env['refresh_cookie']];
try {
$refresh_token = JWT::decode($jwt, new Key($env['refresh_token_secret'], 'HS512'));
} catch(ExpiredException $e) {
throw new Exception("Refresh token expired");
}
if (!$this->test_token($refresh_token)) {
throw new Exception("Invalid refresh token!");
}
$user = $refresh_token->username;
$new_access_token = $this->generate_access_token($user);
$this->refresh_token($user);
return $new_access_token;
}
public function login($user, $password) {
global $env;
if ($user != $env['user'] || $password != $env['password']) {
return null;
}
$access_token = $this->generate_access_token($user);
$this->refresh_token($user);
return $access_token;
}
private function test_token($token) {
global $env;
if (!isset($token->username)) {
return false;
}
if ($token->iss != $env['domain']) {
return false;
}
return $token->nbf <= $this->date->getTimestamp();
}
private function valid_token($jwt) {
global $env;
try {
$token = JWT::decode($jwt, new Key($env['access_token_secret'], 'HS512'));
return $this->test_token($token);
} catch(ExpiredException $e) {
throw new Exception("Access token expired");
}
}
public function __call($method, $params) {
$jwt = array_shift($params);
if (!$this->valid_token($jwt)) {
throw new Exception("Invalid token");
}
$class = get_class($this->service);
$methods = get_class_methods($class);
if (!in_array($method, $methods)) {
throw new Exception("Invalid method $method");
}
return call_user_func_array(array($this->service, $method), $params);
}
}