# `naisi_verify_access_token`

验证访问令牌并立即建立请求级可信登录上下文。

验证开始即清空旧上下文。只有许可、密文认证、时效、client mark 和 tenant
范围全部通过时才将 Access Token 中解析出的数据数组写入 $token_payload；
SaaS 模式下密文 Payload 必须包含 tenant_code，0 表示平台作用域，正整数须获租户许可，输出为 int；缺失即失败；entcustom 不要求该字段。
普通校验、参数类型或授权回执失败时清除旧登录上下文，输出为 null 并返回 false；超出 PHP int 范围的租户编号失败。
输出在输入消费完成后写入，遵循 PHP 类型化属性规则；引擎异常仍按 PHP 原有规则抛出。
naisi_verify_login_session() 用于服务端 login mark 与 IP 二次复核，并为权限解析建立同请求 AUTH 证明。

## 函数签名

```php
function naisi_verify_access_token(string $client_mark, string $access_token, string $salt, ?array &$token_payload = null): bool
```

## 调用前提

应用入口先调用 [naisi_is_ext_license_valid](/web/developers/naisilib/naisi-is-ext-license-valid) 并确认返回 `true`。认证 Agent 发布的许可与 heartbeat 快照，并建立或复用本请求的 BASIC 证明；不会读取许可文件或检查当前 Host。

授权类别：`TOKEN_ESTABLISHES_SESSION`；执行模式：`BASIC`。许可不代替登录、租户或权限上下文；身份与数据要求见本页参数及用途说明。

## 参数

### `$client_mark`

- 类型：`string`
- 必填：是
- 默认值：无
- 方向：输入参数。

固定 18 位 [a-z0-9] 标识：11 位设备摘要、6 位可重复随机字符、1 位校验字符。

### `$access_token`

- 类型：`string`
- 必填：是
- 默认值：无
- 方向：输入参数。

需要验证的访问令牌字符串，最大 64 KiB。

### `$salt`

- 类型：`string`
- 必填：是
- 默认值：无
- 方向：输入参数。

签发时使用的同一份 16 字节业务盐。

### `$token_payload`

- 类型：`?array`
- 必填：否
- 默认值：`null`
- 方向：引用输出参数；失败时清空，仅在成功后包含有效结果。

访问令牌载荷输出参数；成功时写入解码后的数组，普通校验、参数类型或回执失败时为 null。输入消费完成后赋值，支持与 salt 共用变量；类型化属性应允许 null，否则清空时抛出 TypeError 并保留原值。 该参数按引用传递，调用结束后可能被写入输出结果。

## 返回值

类型：`bool`

验证或条件判断成立时返回 true，否则返回 false。

## 调用示例

当前请求须满足上方调用前提；请检查实际返回值和引用输出，随机结果及数据包内容以运行环境为准。

```php
// $token 由签发端生成；$clientMark 和 $salt 与签发时一致。
$tokenPayload = null;
$ok = naisi_verify_access_token($clientMark, $token, $salt, $tokenPayload);
if (!$ok) { throw new RuntimeException('令牌无效'); }
// 成功后才读取 $tokenPayload，并按业务要求复核登录会话。
```

## 升级说明

当前签名用 16 字节的 `$salt` 字符串替代 `$encryption_config` 数组；密钥由扩展从内部 AES 密钥库选择。签发端和验证端须使用相同业务盐。旧调用需修改，已有令牌或 Credential 应重新签发并验证兼容性。

## 版本信息

- 自版本：`1.0.6`
- 实现模块：`auth`
- 授权类别：`TOKEN_ESTABLISHES_SESSION` / `BASIC`
- 失败回退：`false`
- 文档同步：`2026-10-18`
