Skip to content

Commit 9d95a1e

Browse files
committed
feat: 生成令牌可以指定客户端 client 字段,自定义客户端单点登录(默认为WEB,即网页端),如:MOBILEAPPWECHATWEBADMINAPIOTHER等等
1 parent 414c220 commit 9d95a1e

File tree

3 files changed

+47
-31
lines changed

3 files changed

+47
-31
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,18 @@ $exp = Tinywan\Jwt\JwtToken::getTokenExp();
102102
```php
103103
'is_single_device' => true,
104104
```
105+
106+
生成令牌可以指定客户端 `client` 字段,自定义客户端单点登录(默认为`WEB`,即网页端),如:`MOBILE``APP``WECHAT``WEB``ADMIN``API``OTHER`等等
107+
```php
108+
$user = [
109+
'id' => 2022,
110+
'name' => 'Tinywan',
111+
'client' => 'MOBILE',
112+
];
113+
$token = Tinywan\Jwt\JwtToken::generateToken($user);
114+
var_dump(json_encode($token));
115+
```
116+
105117
> 7、获取当前用户信息(模型)
106118
107119
```php

src/JwtToken.php

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,14 @@ class JwtToken
3535
*/
3636
private const REFRESH_TOKEN = 2;
3737

38+
public const TOKEN_CLIENT_WEB = 'WEB';
39+
40+
public const TOKEN_CLIENT_MOBILE = 'MOBILE';
41+
3842
/**
3943
* @desc: 获取当前登录ID
40-
* @throws JwtTokenException
4144
* @return mixed
45+
* @throws JwtTokenException
4246
* @author Tinywan(ShaoBo Wan)
4347
*/
4448
public static function getCurrentId()
@@ -116,12 +120,8 @@ public static function refreshToken(): array
116120
$newToken['refresh_token'] = self::makeToken($payload['refreshPayload'], $refreshSecretKey, $config['algorithms']);
117121
}
118122
if ($config['is_single_device']) {
119-
RedisHandler::generateToken([
120-
'id' => $extend['extend']['id'],
121-
'access_token' => $newToken['access_token'],
122-
'cache_token_ttl' => $extend['exp'],
123-
'cache_token_pre' => $config['cache_token_pre']
124-
]);
123+
$client = $extend['extend']['client'] ?? self::TOKEN_CLIENT_WEB;
124+
RedisHandler::generateToken($config['cache_token_pre'], $client, $extend['extend']['id'], $extend['exp'], $newToken['access_token']);
125125
}
126126
return $newToken;
127127
}
@@ -152,12 +152,8 @@ public static function generateToken(array $extend): array
152152
$token['refresh_token'] = self::makeToken($payload['refreshPayload'], $refreshSecretKey, $config['algorithms']);
153153
}
154154
if ($config['is_single_device']) {
155-
RedisHandler::generateToken([
156-
'id' => $extend['id'],
157-
'access_token' => $token['access_token'],
158-
'cache_token_ttl' => $config['cache_token_ttl'],
159-
'cache_token_pre' => $config['cache_token_pre']
160-
]);
155+
$client = $extend['extend']['client'] ?? self::TOKEN_CLIENT_WEB;
156+
RedisHandler::generateToken($config['cache_token_pre'], $client, $extend['id'], $config['access_exp'], $token['access_token']);
161157
}
162158
return $token;
163159
}
@@ -195,7 +191,7 @@ public static function verify(int $tokenType = self::ACCESS_TOKEN, string $token
195191
*/
196192
private static function getTokenExtend(): array
197193
{
198-
return (array) self::verify()['extend'];
194+
return (array)self::verify()['extend'];
199195
}
200196

201197
/**
@@ -205,7 +201,7 @@ private static function getTokenExtend(): array
205201
*/
206202
public static function getTokenExp(int $tokenType = self::ACCESS_TOKEN): int
207203
{
208-
return (int) self::verify($tokenType)['exp'] - time();
204+
return (int)self::verify($tokenType)['exp'] - time();
209205
}
210206

211207
/**
@@ -255,16 +251,17 @@ private static function verifyToken(string $token, int $tokenType): array
255251
$decoded = JWT::decode($token, new Key($publicKey, $config['algorithms']));
256252
$decodeToken = json_decode(json_encode($decoded), true);
257253
if ($config['is_single_device'] && self::ACCESS_TOKEN == $tokenType) {
258-
RedisHandler::verifyToken($config['cache_token_pre'], (string) $decodeToken['extend']['id'], $token);
254+
$client = $decodeToken['extend']['client'] ?? self::TOKEN_CLIENT_WEB;
255+
RedisHandler::verifyToken($config['cache_token_pre'], $client, (string)$decodeToken['extend']['id'], $token);
259256
}
260257
return $decodeToken;
261258
}
262259

263260
/**
264261
* @desc: 生成令牌.
265262
*
266-
* @param array $payload 载荷信息
267-
* @param string $secretKey 签名key
263+
* @param array $payload 载荷信息
264+
* @param string $secretKey 签名key
268265
* @param string $algorithms 算法
269266
* @return string
270267
*/
@@ -361,13 +358,14 @@ private static function _getConfig(): array
361358

362359
/**
363360
* @desc: 注销令牌
361+
* @param string $client
364362
* @return bool
365363
*/
366-
public static function clear(): bool
364+
public static function clear(string $client = self::TOKEN_CLIENT_WEB): bool
367365
{
368366
$config = self::_getConfig();
369367
if ($config['is_single_device']) {
370-
return RedisHandler::clearToken($config['cache_token_pre'], (string) self::getCurrentId());
368+
return RedisHandler::clearToken($config['cache_token_pre'], $client, (string)self::getCurrentId());
371369
}
372370
return true;
373371
}

src/RedisHandler.php

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,52 +16,58 @@
1616
class RedisHandler
1717
{
1818
/**
19-
* @desc: 生成设备缓存令牌
19+
* @desc: 生成缓存令牌
2020
* (1)登录时,判断该账号是否在其它设备登录,如果有,就请空之前key清除,
21-
* (2)重新设置key 。然后存储用户信息和ip地址拼接为key,存储在redis当中
22-
* @param array $args
21+
* (2)重新设置key,然后存储用户信息在redis当中
22+
* @param string $pre
23+
* @param string $client
24+
* @param string $uid
25+
* @param int $ttl
26+
* @param string $token
2327
* @author Tinywan(ShaoBo Wan)
2428
*/
25-
public static function generateToken(array $args): void
29+
public static function generateToken(string $pre, string $client, string $uid, int $ttl, string $token): void
2630
{
27-
$cacheKey = $args['cache_token_pre'] . $args['id'];
31+
$cacheKey = $pre . $client. ':'. $uid;
2832
$key = Redis::keys($cacheKey . ':*');
2933
if (!empty($key)) {
3034
Redis::del(current($key));
3135
}
32-
Redis::setex($cacheKey . ':' . request()->getRealIp(), $args['cache_token_ttl'], $args['access_token']);
36+
Redis::setex($cacheKey, $ttl, $token);
3337
}
3438

3539
/**
3640
* @desc: 检查设备缓存令牌
3741
* @param string $pre
42+
* @param string $client
3843
* @param string $uid
3944
* @param string $token
4045
* @return bool
4146
* @author Tinywan(ShaoBo Wan)
4247
*/
43-
public static function verifyToken(string $pre, string $uid, string $token): bool
48+
public static function verifyToken(string $pre, string $client, string $uid, string $token): bool
4449
{
45-
$cacheKey = $pre . $uid . ':' . request()->getRealIp();
50+
$cacheKey = $pre . $client. ':'. $uid;
4651
if (!Redis::exists($cacheKey)) {
4752
throw new JwtCacheTokenException('该账号已在其他设备登录,强制下线');
4853
}
4954
if (Redis::get($cacheKey) != $token) {
50-
throw new JwtCacheTokenException('身份验证令牌已失效');
55+
throw new JwtCacheTokenException('身份验证会话已过期,请再次登录!');
5156
}
5257
return true;
5358
}
5459

5560
/**
5661
* @desc: 清理缓存令牌
5762
* @param string $pre
63+
* @param string $client
5864
* @param string $uid
5965
* @return bool
6066
* @author Tinywan(ShaoBo Wan)
6167
*/
62-
public static function clearToken(string $pre, string $uid): bool
68+
public static function clearToken(string $pre, string $client, string $uid): bool
6369
{
64-
$token = Redis::keys($pre . $uid . ':*');
70+
$token = Redis::keys($pre . $client. ':'. $uid . ':*');
6571
if ($token) {
6672
Redis::del(current($token));
6773
}

0 commit comments

Comments
 (0)