PHPackages                             watsonhaw/think-satoken - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Authentication &amp; Authorization](/categories/authentication)
4. /
5. watsonhaw/think-satoken

ActiveLibrary[Authentication &amp; Authorization](/categories/authentication)

watsonhaw/think-satoken
=======================

satoken extend for thinkphp6|8

v1.3.0(2w ago)66752MITPHPPHP ^7.1||^8.0CI passing

Since Dec 25Pushed 2w agoCompare

[ Source](https://github.com/watsonhaw5566/think-satoken)[ Packagist](https://packagist.org/packages/watsonhaw/think-satoken)[ RSS](/packages/watsonhaw-think-satoken/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (8)Dependencies (13)Versions (10)Used By (0)

think-satoken
=============

[](#think-satoken)

项目介绍
----

[](#项目介绍)

think-satoken 是一个轻量级权限认证扩展，专为 ThinkPHP(6|8) 框架设计。追求**简单、直观**，适合中小型项目使用。

设计理念
----

[](#设计理念)

- **极简配置**：5 个核心配置项，开箱即用
- **单端登录**：默认同一账号同一时间只允许一个设备在线（新登录自动顶掉旧设备）
- **直观续期**：使用秒数而非百分比配置续期阈值，无需心算
- **无状态 Token**：使用纯 UUID v4 作为 token，无需签名，依赖缓存存储会话状态
- **缓存隔离**：通过 `store` 配置指定专用缓存通道，避免与业务缓存互相干扰

功能特性
----

[](#功能特性)

- 🔐 **用户认证**：登录、登出、强制踢出
- 🎯 **Token 管理**：UUID v4 格式 token，内置严格格式验证
- 🚫 **权限拦截**：提供 `checkLogin()` 与 `SatokenAuth` 中间件
- ♻️ **智能滑动续期**：`renew_buffer`（秒数）控制续期时机，剩余不足指定秒数时才刷新 TTL，避免每次请求写缓存
- ⏱️ **有效期查询**：过期时间戳与剩余有效秒数查询
- 📦 **自定义附加信息**：登录时可附加 `extra` 数据，支持运行时更新
- ⚡ **高性能**：基于 think-cache 实现，支持 File / Redis 等多种驱动

部署指南
----

[](#部署指南)

### 单机部署

[](#单机部署)

使用默认的 File 缓存即可，无需额外配置。

### 多机/多实例部署

[](#多机多实例部署)

多机部署（负载均衡环境）时，token 会话数据需要在多台服务器之间共享。请在配置中指定 `store` 为 `'redis'`：

```
// config/satoken.php
return [
    'store' => 'redis',
    // ...
];
```

同时确保在 `config/cache.php` 中正确配置 Redis 缓存通道（参考 [ThinkPHP 缓存文档](https://doc.thinkphp.cn/v8_0/caches.html)）：

```
// config/cache.php
return [
    'default' => 'file',
    'stores' => [
        // 业务默认缓存（file）
        'file' => [
            'type' => 'File',
            // ...
        ],
        // SaToken 专用 Redis 缓存
        'redis' => [
            'type' => 'redis',
            'host' => '127.0.0.1',
            'port' => 6379,
            'password' => '',
            'select' => 0,
            'timeout' => 0,
            'persistent' => false,
            'prefix' => 'satoken:',
        ],
    ],
];
```

**为什么需要 Redis？** File 缓存将数据存储在本地文件系统，不同服务器之间无法共享。用户在 A 机登录后，请求打到 B 机时 B 机的文件缓存中没有该 token，会导致误判为未登录。

安装
--

[](#安装)

使用 Composer 安装：

```
composer require watsonhaw/think-satoken
```

配置
--

[](#配置)

配置文件 `config/satoken.php`（发布后）：

```
return [
    // 自定义 Token 请求头名称（为空则使用 Authorization: Bearer {token}）
    'token_name' => '',

    // 缓存通道名称（对应 cache.php 配置中的 stores 键名）
    // null 表示使用框架默认缓存
    // 多机部署请配置为 'redis' 并确保在 cache.php 中正确配置
    'store' => null,

    // Token 有效期（秒），默认 7 天
    'timeout' => 604800,

    // 是否启用滑动续期（用户活跃时自动延长有效期）
    'auto_renew' => true,

    // 续期缓冲时间（秒）：剩余有效期不足此值时才续期
    // 默认 3600 秒（1小时），避免每次请求都写缓存
    // 设为 0 表示每次访问都续期
    'renew_buffer' => 3600,
];
```

**配置说明**：

配置项类型默认值说明`token_name`string`''`自定义请求头名称，为空时从 `Authorization: Bearer` 读取`store`string|null`null`缓存通道名称，对应 `cache.php` 中的 `stores` 键；null 使用默认缓存`timeout`int`604800`Token 有效期（秒），默认 7 天`auto_renew`bool`true`是否启用滑动续期`renew_buffer`int`3600`续期缓冲时间（秒），剩余不足此时才触发续期，设为 0 表示每次访问都续期**滑动续期示例**：

- `timeout` = 604800（7天），`renew_buffer` = 3600（1小时）
- 用户登录后前 6 天访问时**不会**触发写操作（性能最优）
- 当剩余有效期不足 1 小时时访问，自动续期为新的 7 天
- 设 `renew_buffer` = 0 则每次访问都续期（最实时，但写缓存频繁）

**缓存隔离建议**：

即使是单机部署，也建议为 SaToken 配置独立的缓存通道（如单独的 Redis select 或独立的文件目录），通过 `prefix` 区分，便于管理和清理。

使用示例
----

[](#使用示例)

### 1. 登录认证

[](#1-登录认证)

```
use satoken\facade\SaToken;

// 用户登录，返回生成的 token
$token = SaToken::login(1001); // 1001 为用户ID

// 登录时附加自定义数据
$token = SaToken::login(1001, ['role' => 'admin', 'tenant_id' => 42]);

// 检查是否已登录
if (SaToken::isLogin($token)) {
    echo '用户已登录';
}

// 获取当前登录用户ID
$loginId = SaToken::getCurrentLoginId($token);

// 获取自定义附加数据
$extra = SaToken::getExtra($token);

// 更新自定义附加数据（不影响有效期）
SaToken::setExtra($token, ['role' => 'editor']);

// 用户登出
SaToken::logout($token);

// 强制踢出用户（使其当前 token 失效）
SaToken::kickout(1001);

// 强制踢出指定 token
SaToken::kickoutByToken($token);
```

**单端登录行为**：同一账号再次调用 `login()` 时，旧 token 会自动失效（顶号）。

### 2. 使用中间件

[](#2-使用中间件)

`SatokenAuth` 中间件会在请求处理前调用 `checkLogin()` 验证登录状态，验证失败时直接返回 JSON 响应。

在 `app/middleware.php` 中注册：

```
return [
    // 路由中间件
    'router' => [
        'auth' => 'satoken\middleware\SatokenAuth',
    ],
];
```

在路由中使用：

```
Route::get('api/user/profile', 'UserController@profile')->middleware('auth');
```

中间件响应：

状态HTTP 状态码返回 JSON未提供 token401`{"code": ..., "msg": "未提供token", "data": null}`无效 token401`{"code": ..., "msg": "无效的token格式/无效的token", "data": null}`通过校验—放行### 3. 令牌传递

[](#3-令牌传递)

推荐通过请求头传递令牌：

- `Authorization: Bearer `（推荐）
- 或自定义头：`{token_name}: `

```
curl -H "Authorization: Bearer $TOKEN" https://api.example.com/user/profile
```

异常处理
----

[](#异常处理)

```
use satoken\facade\SaToken;
use satoken\exception\NotLoginException;
use satoken\exception\TokenInvalidException;

try {
    SaToken::checkLogin();
    // 已登录，执行业务逻辑
} catch (NotLoginException $e) {
    // 未提供 token
} catch (TokenInvalidException $e) {
    // token 无效或已过期
}
```

核心 API
------

[](#核心-api)

方法说明`createToken(): string`生成 UUID v4 token`validateTokenFormat(string $token): bool`验证 token 格式`login(int $loginId, array $extra = []): string`登录（旧 token 自动失效）`logout(?string $token = null): bool`登出`isLogin(?string $token = null): bool`检查是否已登录`checkLogin(?string $token = null): void`校验登录状态，失败抛异常`getCurrentLoginId(?string $token = null): int`获取当前登录用户 ID`getTokenInfo(?string $token = null): array`获取 token 完整信息`getExtra(?string $token = null): array`获取自定义附加数据`setExtra(?string $token = null, array $extra = []): bool`更新附加数据`getTokenExpireTime(?string $token = null): int`获取过期时间戳`getTokenRemainingTime(?string $token = null): int`获取剩余有效秒数`kickout(int $id): bool`强制踢出用户`kickoutByToken(string $token): bool`强制踢出指定 token缓存键说明
-----

[](#缓存键说明)

键类型TTL说明`satoken:token:{uuid}`array`timeout`token 信息（loginId、create\_time、expire\_time、extra）`satoken:loginId:{id}`string`timeout`用户 ID 到当前 token 的映射（单 token）> 如果配置了 `store` 指向自定义缓存通道（如 Redis），这些键将存储在对应通道中；如果该通道配置了 `prefix`，实际键名会自动加上该前缀。

开发和测试
-----

[](#开发和测试)

```
# 运行单元测试
vendor/bin/phpunit

# 静态分析
vendor/bin/phpstan analyse
```

License
-------

[](#license)

MIT

###  Health Score

47

—

FairBetter than 93% of packages

Maintenance97

Actively maintained with recent releases

Popularity25

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~27 days

Recently: every ~51 days

Total

9

Last Release

17d ago

PHP version history (2 changes)v1.0.0PHP &gt;=8.0

v1.0.3PHP ^7.1||^8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/d52f81ce11644b1118af4d1942981d8c11003c36a0613ba64f162e4c868b057f?d=identicon)[watsonhaw](/maintainers/watsonhaw)

---

Top Contributors

[![watsonhaw5566](https://avatars.githubusercontent.com/u/4210367?v=4)](https://github.com/watsonhaw5566 "watsonhaw5566 (19 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/watsonhaw-think-satoken/health.svg)

```
[![Health](https://phpackages.com/badges/watsonhaw-think-satoken/health.svg)](https://phpackages.com/packages/watsonhaw-think-satoken)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.9k556.2M21.5k](/packages/laravel-framework)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k99.8M354](/packages/laravel-horizon)[directorytree/ldaprecord-laravel

LDAP Authentication &amp; Management for Laravel.

5732.5M23](/packages/directorytree-ldaprecord-laravel)[pocketmine/pocketmine-mp

A server software for Minecraft: Bedrock Edition written in PHP

3.6k79.3k91](/packages/pocketmine-pocketmine-mp)[leantime/leantime

Open source project management system for non-project managers. Simple like Trello, powerful like Jira. Built with neurodiversity in mind.

11.3k4.0k](/packages/leantime-leantime)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.8M672](/packages/shopware-core)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
