UserTokenService.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <?php
  2. namespace app\data\service;
  3. use app\data\model\DataUserToken;
  4. use think\admin\Service;
  5. /**
  6. * 用户接口授权服务
  7. * Class UserTokenService
  8. * @package app\data\service
  9. */
  10. class UserTokenService extends Service
  11. {
  12. /**
  13. * 认证有效时间
  14. * @var integer
  15. */
  16. private $expire = 7200;
  17. /**
  18. * 检查 TOKEN 是否有效
  19. * @param string $type 接口类型
  20. * @param string $token 认证令牌
  21. * @param array $data 认证数据
  22. * @return array [ 检查状态,状态描述,用户UID, 有效时间 ]
  23. * @throws \think\db\exception\DataNotFoundException
  24. * @throws \think\db\exception\DbException
  25. * @throws \think\db\exception\ModelNotFoundException
  26. */
  27. public function check(string $type, string $token, array $data = []): array
  28. {
  29. if (empty($data)) {
  30. $map = ['type' => $type, 'token' => $token];
  31. $data = DataUserToken::mk()->where($map)->find();
  32. }
  33. if (empty($data) || empty($data['uuid'])) {
  34. return [0, '请重新登录,登录认证无效', 0, 0];
  35. } elseif ($token !== 'token' && $data['time'] < time()) {
  36. return [0, '请重新登录,登录认证失效', 0, 0];
  37. } elseif ($token !== 'token' && $data['tokenv'] !== $this->_buildTokenVerify()) {
  38. return [0, '请重新登录,客户端已更换', 0, 0];
  39. } else {
  40. $this->expire($type, $token);
  41. return [1, '登录验证成功', $data['uuid'], $data['time']];
  42. }
  43. }
  44. /**
  45. * 获取令牌的认证值
  46. * @return string
  47. */
  48. private function _buildTokenVerify(): string
  49. {
  50. return md5($this->app->request->server('HTTP_USER_AGENT', '-'));
  51. }
  52. /**
  53. * 延期 TOKEN 有效时间
  54. * @param string $type 接口类型
  55. * @param string $token 授权令牌
  56. */
  57. public function expire(string $type, string $token)
  58. {
  59. $map = ['type' => $type, 'token' => $token];
  60. DataUserToken::mk()->where($map)->update([
  61. 'time' => time() + $this->expire,
  62. ]);
  63. }
  64. /**
  65. * 生成新的用户令牌
  66. * @param int $uuid 授权用户
  67. * @param string $type 接口类型
  68. * @return array [创建状态, 状态描述, 令牌数据]
  69. */
  70. public function token(int $uuid, string $type): array
  71. {
  72. // 清理无效认证数据
  73. $time = time();
  74. $map1 = [['token', '<>', 'token'], ['time', '<', $time]];
  75. $map2 = [['token', '<>', 'token'], ['type', '=', $type], ['uuid', '=', $uuid]];
  76. DataUserToken::mk()->whereOr([$map1, $map2])->delete();
  77. // 创建新的认证数据
  78. do $map = ['type' => $type, 'token' => md5(uniqid() . rand(100, 999))];
  79. while (DataUserToken::mk()->where($map)->count() > 0);
  80. // 写入用户认证数据
  81. $data = array_merge($map, ['uuid' => $uuid, 'time' => $time + $this->expire, 'tokenv' => $this->_buildTokenVerify()]);
  82. if (DataUserToken::mk()->insert($data) !== false) {
  83. return [1, '刷新认证成功', $data];
  84. } else {
  85. return [0, '刷新认证失败', []];
  86. }
  87. }
  88. }