Completed
Push — master ( ee280a...529931 )
by John
01:02 queued 57s
created

JwtToken::getSubject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
/*
3
 * This file is part of the KleijnWeb\JwtBundle package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace KleijnWeb\JwtBundle\Authenticator;
10
11
use KleijnWeb\JwtBundle\Authenticator\SignatureValidator\SignatureValidator;
12
13
/**
14
 * @author John Kleijn <[email protected]>
15
 */
16
class JwtToken
17
{
18
    /**
19
     * @var array
20
     */
21
    private $claims = [];
22
23
    /**
24
     * @var array
25
     */
26
    private $header = [];
27
28
    /**
29
     * @var int
30
     */
31
    private $payload;
32
33
    /**
34
     * @var string
35
     */
36
    private $signature;
37
38
    /**
39
     * @var string
40
     */
41
    private $tokenString;
42
43
    /**
44
     * @param $tokenData
45
     */
46
    public function __construct($tokenData)
47
    {
48
        if (is_array($tokenData)) {
49
            $this->setTokenFromParams($tokenData['header'], $tokenData['claims'], $tokenData['secret']);
50
        } else {
51
            $this->setTokenFromString($tokenData);
52
        }
53
    }
54
55
    /**
56
     * @param string $tokenString
57
     */
58
    public function setTokenFromString($tokenString)
59
    {
60
        $this->tokenString = $tokenString;
61
        $segments          = explode('.', $tokenString);
62
63
        if (count($segments) !== 3) {
64
            throw new \InvalidArgumentException("Not a JWT token string");
65
        }
66
67
        list($headerBase64, $claimsBase64, $signatureBase64) = $segments;
68
69
        $this->payload = "{$headerBase64}.{$claimsBase64}";
70
71
        $decoder         = new Decoder();
72
        $this->header    = $decoder->decode($headerBase64);
73
        $this->claims    = $decoder->decode($claimsBase64);
74
        $this->signature = $decoder->base64Decode($signatureBase64);
75
    }
76
77
    /**
78
     * @param array $header
79
     * @param array $claims
80
     * @param       $secret
81
     */
82
    public function setTokenFromParams($header, $claims, $secret)
83
    {
84
        $this->header = $header;
85
        $this->claims = $claims;
86
87
        $encoder      = new Encoder();
88
        $headerBase64 = $encoder->encode($header);
89
        $claimsBase64 = $encoder->encode($claims);
90
91
        $this->payload = "{$headerBase64}.{$claimsBase64}";
92
93
        $this->signature = hash_hmac(
94
            'sha256',
95
            $this->payload,
96
            $secret,
97
            true
98
        );
99
        $signatureBase64 = $encoder->base64Encode($this->signature);
100
101
        $segments          = compact('headerBase64', 'claimsBase64', 'signatureBase64');
102
        $this->tokenString = implode('.', $segments);
103
    }
104
105
    /**
106
     * @return string|null
107
     */
108
    public function getKeyId()
109
    {
110
        return isset($this->header['kid']) ? $this->header['kid'] : null;
111
    }
112
113
    /**
114
     * @param string             $secret
115
     * @param SignatureValidator $validator
116
     *
117
     * @throws \InvalidArgumentException
118
     */
119
    public function validateSignature($secret, SignatureValidator $validator)
120
    {
121
        if (!$validator->isValid($this->payload, $secret, $this->signature)) {
122
            throw new \InvalidArgumentException("Invalid signature");
123
        }
124
    }
125
126
    /**
127
     * @return array
128
     */
129
    public function getSubject()
130
    {
131
        if (isset($this->claims['sub'])) {
132
            return $this->claims['sub'];
133
        }
134
135
        return $this->claims['prn'];
136
    }
137
138
    /**
139
     * @return array
140
     */
141
    public function getClaims()
142
    {
143
        return $this->claims;
144
    }
145
146
    /**
147
     * @return array
148
     */
149
    public function getHeader()
150
    {
151
        return $this->header;
152
    }
153
154
    /**
155
     * @return string
156
     */
157
    public function getTokenString()
158
    {
159
        return $this->tokenString;
160
    }
161
162
163
}
164