1 | <?php |
||||
2 | |||||
3 | |||||
4 | namespace ArcherZdip\LaravelApiAuth; |
||||
5 | |||||
6 | use Exception; |
||||
7 | use Carbon\Carbon; |
||||
0 ignored issues
–
show
|
|||||
8 | use ArcherZdip\LaravelApiAuth\Models\AppClient; |
||||
9 | use function ArcherZdip\LaravelApiAuth\Helper\base64_urlsafe_decode; |
||||
10 | use function ArcherZdip\LaravelApiAuth\Helper\base64_urlsafe_encode; |
||||
11 | |||||
12 | class ApiAuth |
||||
13 | { |
||||
14 | /** |
||||
15 | * @var string $token |
||||
16 | */ |
||||
17 | protected $token; |
||||
18 | |||||
19 | /** |
||||
20 | * @var array $validKeys |
||||
21 | */ |
||||
22 | protected $validKeys = ['appid', 'token', 'exp']; |
||||
23 | |||||
24 | public function __construct(string $token) |
||||
25 | { |
||||
26 | $this->token = $token; |
||||
27 | |||||
28 | $this->verifySign(); |
||||
29 | } |
||||
30 | |||||
31 | /** |
||||
32 | * Check token is valid |
||||
33 | * |
||||
34 | * @param string $token |
||||
35 | * @return bool |
||||
36 | */ |
||||
37 | public static function isValid(string $token): bool |
||||
38 | { |
||||
39 | try { |
||||
40 | new static($token); |
||||
41 | return true; |
||||
42 | } catch (Exception $exception) { |
||||
43 | return false; |
||||
44 | } |
||||
45 | } |
||||
46 | |||||
47 | /** |
||||
48 | * Get Appid by token |
||||
49 | * |
||||
50 | * @param string $token |
||||
51 | * @return string |
||||
52 | */ |
||||
53 | public static function getAppId(string $token): string |
||||
54 | { |
||||
55 | return explode('.', base64_urlsafe_decode($token))[0] ?? ''; |
||||
56 | } |
||||
57 | |||||
58 | /** |
||||
59 | * Generate token, for test token is valid |
||||
60 | * |
||||
61 | * @param string $appid |
||||
62 | * @param int|null $exp |
||||
63 | * @return string |
||||
64 | * @throws Exception |
||||
65 | */ |
||||
66 | public static function generateToken(string $appid, int $exp = null): string |
||||
67 | { |
||||
68 | if ($exp === null) { |
||||
69 | $exp = time(); |
||||
70 | } |
||||
71 | |||||
72 | $appClient = AppClient::getSecretByAppId($appid); |
||||
73 | if (!$appClient) { |
||||
74 | throw new Exception("The AppId is not exists"); |
||||
75 | } |
||||
76 | $secret = $appClient->secret; |
||||
77 | $sign = sha1($appid . $secret . $exp); |
||||
78 | |||||
79 | return base64_urlsafe_encode(implode('.', [$appid, $sign, $exp])); |
||||
80 | } |
||||
81 | |||||
82 | /** |
||||
83 | * Check appid |
||||
84 | * |
||||
85 | * @param string $appid |
||||
86 | * @return AppClient $appClient |
||||
87 | * @throws Exception |
||||
88 | */ |
||||
89 | protected function checkAppId(string $appid): ?AppClient |
||||
90 | { |
||||
91 | $appClient = AppClient::getSecretByAppId($appid); |
||||
92 | if (!$appClient) { |
||||
93 | throw new Exception("The AppId is not exists"); |
||||
94 | } |
||||
95 | |||||
96 | return $appClient; |
||||
97 | } |
||||
98 | |||||
99 | /** |
||||
100 | * verify sign |
||||
101 | * |
||||
102 | * @return null |
||||
103 | * @throws Exception |
||||
104 | */ |
||||
105 | protected function verifySign() |
||||
106 | { |
||||
107 | [$appid, $sign, $exp] = $this->tokenDecode($this->token); |
||||
108 | |||||
109 | // check timeout |
||||
110 | $now = Carbon::now()->timestamp; |
||||
111 | $tokenTimeout = (int)config('apikey.token_timeout', 0); |
||||
0 ignored issues
–
show
The function
config was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
112 | if ($tokenTimeout !== 0 && $exp + $tokenTimeout > $now) { |
||||
113 | throw new Exception('Token is timeout.'); |
||||
114 | } |
||||
115 | |||||
116 | if ($this->createSign($appid, $exp) !== $sign) { |
||||
0 ignored issues
–
show
$exp of type string is incompatible with the type integer expected by parameter $exp of ArcherZdip\LaravelApiAuth\ApiAuth::createSign() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||
117 | throw new Exception('Token is error.'); |
||||
118 | } |
||||
119 | |||||
120 | return null; |
||||
121 | } |
||||
122 | |||||
123 | /** |
||||
124 | * create sign |
||||
125 | * |
||||
126 | * @param string $appid |
||||
127 | * @param int $exp |
||||
128 | * @return string |
||||
129 | * @throws Exception |
||||
130 | */ |
||||
131 | protected function createSign(string $appid, int $exp): string |
||||
132 | { |
||||
133 | $secret = $this->checkAppId($appid)->secret; |
||||
134 | return sha1($appid . $secret . (string)$exp); |
||||
135 | } |
||||
136 | |||||
137 | /** |
||||
138 | * Token decode |
||||
139 | * |
||||
140 | * @param string $token |
||||
141 | * @return array|null |
||||
142 | * @throws Exception |
||||
143 | */ |
||||
144 | protected function tokenDecode(string $token): ?array |
||||
145 | { |
||||
146 | $data = explode('.', base64_urlsafe_decode($token)); |
||||
147 | if (count($this->validKeys) !== count($data)) { |
||||
148 | throw new Exception('token invalid'); |
||||
149 | } |
||||
150 | |||||
151 | return $data; |
||||
152 | } |
||||
153 | } |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths