• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

miaoxing / plugin / 7048390524

30 Nov 2023 03:02PM UTC coverage: 39.661% (+0.5%) from 39.147%
7048390524

push

github

twinh
ci: update package version

936 of 2360 relevant lines covered (39.66%)

18.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

50.0
/src/Service/Jwt.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace Miaoxing\Plugin\Service;
6

7
use Ahc\Jwt\JWT as AJtw;
8
use Ahc\Jwt\JWTException;
9
use Miaoxing\Plugin\BaseService;
10
use ReqMixin;
11

12
/**
13
 * @mixin ReqMixin
14
 */
15
class Jwt extends BaseService
16
{
17
    public const CODE_EXPIRED = 200007;
18

19
    /**
20
     * @var string
21
     */
22
    protected $algo = 'RS256';
23

24
    /**
25
     * @var string
26
     */
27
    protected $privateKey = 'storage/keys/private.key';
28

29
    /**
30
     * @var string
31
     */
32
    protected $publicKey = 'storage/keys/public.key';
33

34
    /**
35
     * @var array
36
     */
37
    protected $messages = [
38
        AJtw::ERROR_TOKEN_INVALID => '解析 Token 失败',
39
        AJtw::ERROR_SIGNATURE_FAILED => 'Token 签名错误',
40
        AJtw::ERROR_TOKEN_EXPIRED => [
41
            'code' => self::CODE_EXPIRED,
42
            'message' => 'Token 已过期',
43
        ],
44
    ];
45

46
    /**
47
     * @return string
48
     * @svc
49
     */
50
    protected function getPrivateKey(): string
51
    {
52
        return $this->privateKey;
24✔
53
    }
54

55
    /**
56
     * @param string $privateKey
57
     * @return $this
58
     * @svc
59
     */
60
    protected function setPrivateKey(string $privateKey): self
61
    {
62
        $this->privateKey = $privateKey;
×
63
        return $this;
×
64
    }
65

66
    /**
67
     * @return string
68
     * @svc
69
     */
70
    protected function getPublicKey(): string
71
    {
72
        return $this->publicKey ?: $this->privateKey;
×
73
    }
74

75
    /**
76
     * @param string $publicKey
77
     * @return $this
78
     * @svc
79
     */
80
    protected function setPublicKey(string $publicKey): self
81
    {
82
        $this->publicKey = $publicKey;
×
83
        return $this;
×
84
    }
85

86
    /**
87
     * @param array $claims
88
     * @param int $expire
89
     * @return string
90
     * @throws \Exception
91
     * @svc
92
     */
93
    protected function generate(array $claims, int $expire = 86400 * 30): string
94
    {
95
        $jwt = new AJtw($this->getPrivateKey(), $this->algo);
21✔
96

97
        return $jwt->encode(array_merge([
21✔
98
            'iss' => $this->req->getSchemeAndHost(),
21✔
99
            'iat' => time(),
21✔
100
            'exp' => time() + $expire,
21✔
101
        ], $claims), [
21✔
102
            'jti' => base64_encode(random_bytes(8)),
21✔
103
        ]);
14✔
104
    }
105

106
    /**
107
     * @param string $token
108
     * @return Ret
109
     * @svc
110
     */
111
    protected function verify(string $token): Ret
112
    {
113
        if (!$token) {
18✔
114
            return err('Token 不能为空');
3✔
115
        }
116

117
        $jwt = new AJtw($this->getPrivateKey(), $this->algo);
15✔
118

119
        try {
120
            $payload = $jwt->decode($token);
15✔
121
        } catch (JWTException $e) {
9✔
122
            $message = $this->messages[$e->getCode()] ?? $e->getMessage();
9✔
123
            return err($message);
9✔
124
        }
125

126
        if (isset($payload['iss']) && $payload['iss'] !== $this->req->getSchemeAndHost()) {
6✔
127
            return err('Token 内容错误');
3✔
128
        }
129

130
        return suc(['data' => $payload]);
3✔
131
    }
132

133
    /**
134
     * 生成默认配置所需的密钥
135
     *
136
     * @svc
137
     * @experimental
138
     */
139
    protected function generateDefaultKeys(): Ret
140
    {
141
        $res = openssl_pkey_new([
×
142
            'private_key_bits' => 2048,
×
143
            'private_key_type' => \OPENSSL_KEYTYPE_RSA,
144
        ]);
145

146
        openssl_pkey_export($res, $privateKey);
×
147

148
        $details = openssl_pkey_get_details($res);
×
149
        $publicKey = $details['key'];
×
150

151
        $ret = $this->write($this->publicKey, $publicKey);
×
152
        if ($ret->isErr()) {
×
153
            return $ret;
×
154
        }
155
        return $this->write($this->privateKey, $privateKey);
×
156
    }
157

158
    protected function write($path, $content): Ret
159
    {
160
        $dir = dirname($path);
×
161
        if (!is_dir($dir) && !@mkdir($dir, 0777, true) && !is_dir($dir)) {
×
162
            return err(['创建目录 %s 失败,请检查是否有权限操作', $dir]);
×
163
        }
164

165
        file_put_contents($path, $content);
×
166
        return suc();
×
167
    }
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc