123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- <?php
- namespace App\Services\Login;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Query\Builder;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Request;
- use Illuminate\Support\Str;
- use Laravel\Sanctum\PersonalAccessToken;
- use phpDocumentor\Reflection\Types\Boolean;
- class LoginTokenService
- {
- protected string $table = '';
- protected int $expireTime = 3 * 24 * 3600; // 有效期为0 则为永久有效
- public function __construct($userTable)
- {
- $this->table = $userTable;
- }
- /**
- * 同一个用户设备 只允许在线一个
- *
- * @param int $userId
- * @param string $deviceName
- * @return string
- */
- public function createOnlyOneToken(int $userId, string $deviceName): string
- {
- $isExist = DB::table($this->table)
- ->select('id')
- ->where('user_id', $userId)
- ->where('name', $deviceName)->first();
- if ($isExist) {
- // 更新登录信息
- return $this->updateToken($isExist->id);
- } else {
- return $this->createToken($userId, $deviceName);
- }
- }
- /**
- * 创建token
- *
- * @param int $userId
- * @param string $deviceName
- * @return string
- */
- public function createToken(int $userId, string $deviceName): string
- {
- $id = DB::table($this->table)->insertGetId([
- 'mid' => Str::random(12),
- 'user_id' => $userId,
- 'name' => $deviceName,
- 'token' => hash('sha256', $plainTextToken = Str::random(40)),
- 'created_at' => time(),
- 'updated_at' => time()
- ]);
- return base64_encode($id) . '|' . $plainTextToken;
- }
- /**
- * @param int $id
- * @return string
- */
- private function updateToken(int $id): string
- {
- DB::table($this->table)->where(['id' => $id])->update([
- 'token' => hash('sha256', $plainTextToken = Str::random(40)),
- 'updated_at' => time()
- ]);
- return base64_encode($id) . '|' . $plainTextToken;
- }
- /**
- * 判断是否已经登录
- *
- * @return Model|Builder|mixed|object|void|null
- */
- public function checkLogin()
- {
- return $this->findToken($this->getToken());
- }
- /**
- * Find the token instance matching the given token.
- *
- * @param string|null $token
- * @return Model|Builder|mixed|object|void|null
- */
- public function findToken(?string $token)
- {
- if (empty($token)) {
- return null;
- }
- if (!str_contains($token, '|')) {
- return DB::table($this->table)->where('token', hash('sha256', $token))->first();
- }
- [$id, $token] = explode('|', $token, 2);
- $id = base64_decode($id);
- if ($instance = DB::table($this->table)->find($id)) {
- return hash_equals($instance->token, hash('sha256', $token)) ? $instance : null;
- }
- }
- /**
- * 撤销当前令牌
- *
- * @return bool
- */
- public function destroyCurrentAccessToken(): bool
- {
- $token = $this->getToken();
- if (!str_contains($token, '|')) {
- return DB::table($this->table)->where('token', hash('sha256', $token))->delete();
- }
- [$id, $token] = explode('|', $token, 2);
- return DB::table($this->table)->where('token', hash('sha256', $token))->delete();
- }
- /**
- * 获取登录的token
- *
- * @return string|null
- */
- public function getToken(): ?string
- {
- $token = Request::header('Authorization');
- if (empty($token)) {
- // 兼容老版本 2022-7-28
- $token = Request::header('x-token');
- }
- // 允许从cookie中获取
- if (empty($token)) {
- $token = $_COOKIE['officialToken'] ?? '';
- }
- return $token;
- }
- }
|