## `Token` 组件 Token 组件可以理解为 API 中使用的 Session,因为 API 是脱离 Cookie 的,Session 无法运行,所以 API 通常是在 GET/POST/HEADER 中带上一个 access_token 参数来保持会话状态,MixPHP 提供了 Token 来帮助用户在 API 中操作会话。 | 类 | 调用 | | --- | --- | --- | | mix\http\Token | app()->token | | 门面类 | 调用 | | --- | --- | | mix\facades\Token | Token:: | >[danger] Token 组件暂时只支持 Redis,使用前需先安装 Redis 数据库。 ## 组件配置 App配置文件中,该组件的默认配置如下: ~~~ // Token 'token' => [ // 类路径 'class' => 'mix\http\Token', // 保存处理者 'saveHandler' => [ // 类路径 'class' => 'mix\client\Redis', // 主机 'host' => '127.0.0.1', // 端口 'port' => 6379, // 数据库 'database' => 0, // 密码 'password' => '', ], // 保存的Key前缀 'saveKeyPrefix' => 'MIXTKID:', // 有效期 'expires' => 604800, // token键名 'name' => 'access_token', ], ~~~ ## 使用场景 Token 通常有三种使用场景: - 通过 username、password 获取 access_token,用于授权给客户端,使用 access_token 可调用用户相关的接口。 - 通过 appid、appsecret、grant_type 获取 access_token,用于授权给第三方,使用 access_token 可调用平台内 grant_type 参数定义的相关权限的接口。 - OAuth 2.0:将自己平台内获取用户相关信息的权限授权给第三方。 >[info] Token 其实是使用 Redis 组件开发的组件,参考源代码可改造出 OAuth 2.0 Token。 ## 使用范例 第一种使用场景的范例代码。 获取 Token,控制器: ~~~ // 获取 token 方法 public function actionToken() { /* 验证账号密码成功后 */ // 创建 tokenId Token::createTokenId(); // 保存会话信息 $userinfo = [ 'uid' => 1088, 'openid' => 'yZmFiZDc5MjIzZDMz', 'username' => '小明', ]; Token::set('userinfo', $userinfo); // 设置唯一索引 Token::setUniqueIndex($userinfo['openid']); // 响应 return [ 'errcode' => 0, 'access_token' => Token::getTokenId(), 'expires_in' => app()->token->expires, 'openid' => $userinfo['openid'], ]; } ~~~ 效验Token: 在前置中间件中校验。 ~~~ // 前置中间件的 handle 方法 public function handle($callable, \Closure $next) { // 添加中间件执行代码 $userinfo = Token::get('userinfo'); if (empty($userinfo)) { // 返回错误码 return ['errcode' => 300000, 'errmsg' => 'Permission denied']; } // 执行下一个中间件 return $next(); } ~~~ ## `createTokenId` 方法 >[danger] 需要在 set **前**使用。 创建一个TokenId。 ## `setUniqueIndex` 方法 >[danger] 需要在 set **后**使用。 设置唯一索引,设置后会从上次设置的索引找出上次的tokenId,并删除上次的token数据,使上次的token失效,然后再将本次的tokenId存入索引。 ~~~ Token::setUniqueIndex($openid); ~~~ ## `set` 方法 变量赋值。 ~~~ Token::set('name', '小华'); ~~~ ## `get` 方法 获取变量的值。 ~~~ Token::get('name'); ~~~ >[info] name不存在时返回null。 ## `has` 方法 判断变量是否存在。 ~~~ Token::has('name'); ~~~ ## `delete` 方法 删除变量。 ~~~ Token::delete('name'); ~~~ ## `clear` 方法 清空全部变量。 ~~~ Token::clear(); ~~~ ## `getTokenId` 方法 获取TokenId。 ~~~ Token::getTokenId(); ~~~ ## `refresh` 方法 刷新 token,在旧 token 有效期内,生成一个新的 token,刷新成功后可通过 getTokenId 获取新的 tokenId。 ~~~ Token::refresh(); ~~~