Completed
Pull Request — master (#14)
by Artem
06:19
created

JwtGenerator   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 92
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 1
dl 0
loc 92
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
 * This file is part of the FreshCentrifugoBundle.
4
 *
5
 * (c) Artem Henvald <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Fresh\CentrifugoBundle\Service\Jwt;
14
15
use Fresh\CentrifugoBundle\Token\JwtPayloadInterface;
16
17
/**
18
 * JwtGenerator.
19
 *
20
 * @author Artem Henvald <[email protected]>
21
 */
22
class JwtGenerator
23
{
24
    private const HMAC_ALGORITHM = 'sha256';
25
26
    private string $secret;
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION or T_CONST
Loading history...
27
28
    /**
29
     * @param string $centrifugoSecret
30
     */
31
    public function __construct(string $centrifugoSecret)
32
    {
33
        $this->secret = $centrifugoSecret;
34
    }
35
36
    /**
37
     * @param JwtPayloadInterface $payload
38
     *
39
     * @return string
40
     */
41
    public function generateToken(JwtPayloadInterface $payload): string
42
    {
43
        $headerPart = $this->buildHeaderPart();
44
        $payloadPart = $this->buildPayloadPart($payload);
45
46
        $headerPartEncoded = $this->base64EncodeUrlSafe($headerPart);
47
        $payloadPartEncoded = $this->base64EncodeUrlSafe($payloadPart);
48
49
        return \implode('.', [
50
            $headerPartEncoded,
51
            $payloadPartEncoded,
52
            $this->buildSignaturePart($headerPartEncoded, $payloadPartEncoded),
53
        ]);
54
    }
55
56
    /**
57
     * @return string
58
     */
59
    private function buildHeaderPart(): string
60
    {
61
        $header = [
62
            'typ' => 'JWT',
63
            'alg' => 'HS256',
64
        ];
65
66
        return $this->convertArrayToJsonString($header);
67
    }
68
69
    /**
70
     * @param JwtPayloadInterface $payload
71
     *
72
     * @return string
73
     */
74
    private function buildPayloadPart(JwtPayloadInterface $payload): string
75
    {
76
        return $this->convertArrayToJsonString($payload->getPayloadData());
77
    }
78
79
    /**
80
     * @param string $headerPartDecoded
81
     * @param string $payloadPartDecoded
82
     *
83
     * @return string
84
     */
85
    private function buildSignaturePart(string $headerPartDecoded, string $payloadPartDecoded): string
86
    {
87
        $data = $headerPartDecoded.'.'.$payloadPartDecoded;
88
        $hash = \hash_hmac(self::HMAC_ALGORITHM, $data, $this->secret, true);
89
90
        return $this->base64EncodeUrlSafe($hash);
91
    }
92
93
    /**
94
     * @param array $array
95
     *
96
     * @return string
97
     */
98
    private function convertArrayToJsonString(array $array): string
99
    {
100
        return \json_encode($array, \JSON_THROW_ON_ERROR);
101
    }
102
103
    /**
104
     * @param string $string
105
     *
106
     * @return string
107
     */
108
    private function base64EncodeUrlSafe(string $string): string
109
    {
110
        return \str_replace(['+', '/', '='], ['-', '_', ''], \base64_encode($string));
111
    }
112
}
113