Token::getError()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Source\Core;
4
5
use Source\Core\Redis;
6
7
class Token
8
{
9
    private $token;
10
11
    private $timeout;
12
13
    private $error;
14
15
    private $Redis;
16
17
    public function __construct(int $timeout = 1 * 60 * 60)
18
    {
19
        $this->timeout = $timeout;
20
21
        $this->Redis = (new Redis())->getClient();
22
    }
23
24
    /**
25
     * @param string $jwt
26
     * @param string $secret
27
     * @return bool
28
     */
29
    public function validateToken(string $jwt, string $secret = CONF_JWT_SECRET): bool
30
    {
31
        $tokenParts = explode('.', $jwt);
32
        $payload = base64_decode($tokenParts[1]);
33
34
        $signature = hash_hmac('sha256', base64UrlEncode(base64_decode($tokenParts[0])) . "." . base64UrlEncode($payload), $secret, true);
35
36
        if (!(base64UrlEncode($signature) === $tokenParts[2])) {
37
            $this->error = 'this token is invalid';
38
            return false;
39
        }
40
41
        if (!$this->Redis->get((json_decode($payload)->id . json_decode($payload)->expirationTime))) {
42
            $this->error = 'please login first';
43
            return false;
44
        }
45
46
        if ((json_decode($payload)->expirationTime - (time()) <= 0) ? true : false) {
47
            $this->error = 'token expired';
48
            $this->Redis->del((json_decode($payload)->id . json_decode($payload)->expirationTime));
49
            return false;
50
        }
51
52
        $this->token = $payload;
53
        return true;
54
    }
55
56
    /**
57
     * @param object $data
58
     * @param array $context
59
     * @param string $secret
60
     * @return
61
     */
62
    public function generateNewToken(object $data, array $context = CONF_JWT_CONTEXT, string $secret = CONF_JWT_SECRET): string
63
    {
64
        $data = array_merge((array) $data, [
65
            'expirationTime' => (time() + $this->timeout)
66
        ]);
67
68
        $base64UrlHeader = base64UrlEncode(json_encode($context));
69
        $base64UrlPayload = base64UrlEncode(json_encode($data));
70
71
        $parsedPayload = "{$base64UrlHeader}.{$base64UrlPayload}";
72
73
        $token = "{$parsedPayload}." . base64UrlEncode(hash_hmac('sha256', $parsedPayload, $secret, true));
74
75
        $this->Redis->set($data['id'] . $data['expirationTime'], $token, 'EX', $this->timeout);
76
77
        return $token;
78
    }
79
80
    public function getError(): string
81
    {
82
        return $this->error;
83
    }
84
85
    public function getToken(): array
86
    {
87
        return (array) json_decode($this->token);
88
    }
89
}
90