Jwt   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 28
c 2
b 0
f 0
dl 0
loc 106
rs 10
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A generateSignature() 0 9 2
A generateToken() 0 12 2
A base64EncodeUrlSafe() 0 3 1
A base64DecodeUrlSafe() 0 10 2
A validateToken() 0 23 6
1
<?php
2
3
namespace IonGhitun\JwtToken;
4
5
use Carbon\Carbon;
6
use IonGhitun\JwtToken\Exceptions\JwtException;
7
8
/**
9
 * Class Jwt
10
 *
11
 * @package IonGhitun\JwtToken
12
 */
13
class Jwt
14
{
15
    /**
16
     * Generate a new JWT token.
17
     *
18
     * @param  array  $payload
19
     *
20
     * @return string
21
     */
22
    public static function generateToken(array $payload): string
23
    {
24
        $header = self::base64EncodeUrlSafe(json_encode(['typ' => 'JWT', 'alg' => 'HS256']));
25
26
        if (!isset($payload['expiration'])) {
27
            $payload['expiration'] = Carbon::now()->addDay()->format('Y-m-d H:i:s');
28
        }
29
30
        $payload = self::base64EncodeUrlSafe(json_encode($payload));
31
        $signature = self::generateSignature($header, $payload);
32
33
        return $header.".".$payload.".".$signature;
34
    }
35
36
    /**
37
     * Url safe base 64 encode.
38
     *
39
     * @param  string  $string
40
     *
41
     * @return string|string[]
42
     */
43
    private static function base64EncodeUrlSafe(string $string)
44
    {
45
        return str_replace('=', '', strtr(base64_encode($string), '+/', '-_'));
46
    }
47
48
    /**
49
     * Generate signature
50
     *
51
     * @param $header
52
     * @param $payload
53
     * @param  bool  $encode
54
     *
55
     * @return string|string[]
56
     */
57
    private static function generateSignature($header, $payload, $encode = true)
58
    {
59
        $signature = hash_hmac('sha256', $header.'.'.$payload, getenv('JWT_SECRET'), true);
60
61
        if ($encode) {
62
            return self::base64EncodeUrlSafe($signature);
63
        }
64
65
        return $signature;
66
    }
67
68
    /**
69
     * Validate JWT token and return payload
70
     *
71
     * @param $token
72
     *
73
     * @return mixed
74
     *
75
     * @throws JwtException
76
     */
77
    public static function validateToken($token)
78
    {
79
        $tokenData = explode('.', $token);
80
81
        if (count($tokenData) !== 3) {
82
            throw new JwtException('Not a valid JWT token!');
83
        }
84
85
        list($header64, $payload64, $signature64) = $tokenData;
86
87
        $payload = json_decode(self::base64DecodeUrlSafe($payload64), true);
88
89
        if (!$payload || !isset($payload['expiration']) || Carbon::parse($payload['expiration']) < Carbon::now()) {
90
            throw new JwtException('Jwt token expired!');
91
        }
92
93
        $signature = self::base64DecodeUrlSafe($signature64);
94
95
        if ($signature !== self::generateSignature($header64, $payload64, false)) {
96
            throw new JwtException('Could not verify Jwt token signature!');
97
        }
98
99
        return $payload;
100
    }
101
102
    /**
103
     * Url safe base 64 decode.
104
     *
105
     * @param $string
106
     *
107
     * @return false|string
108
     */
109
    private static function base64DecodeUrlSafe($string)
110
    {
111
        $mod = strlen($string) % 4;
112
113
        if ($mod !== 0) {
114
            $padLen = 4 - $mod;
115
            $string .= str_repeat('=', $padLen);
116
        }
117
118
        return base64_decode(strtr($string, '-_', '+/'));
119
    }
120
}
121