128], ]; } /** * {@inheritdoc} */ public function attributeLabels() { return [ 'id' => 'ID', 'cx_mch_id' => '平台商户ID', 'user_id' => '用户ID', 'type' => '类型', 'token' => '令牌', 'expire_time' => '失效时间', 'status' => '状态,0=未验证,1=验证通过,2=验证未通过,3=已失效', 'is_delete' => '是否删除,0=否,1=是', 'created_at' => '添加时间', ]; } public function beforeSave($insert) { if(parent::beforeSave($insert)){ if($this->isNewRecord){ } return true; } else { return false; } } /** * 生成token * @param integer $type 类型 * @param integer $len token长度 * @param integer $retry 重试次数 */ public static function generate($type = self::TYPE_WXAPP_LOGIN, $len = 12, $retry = 3, $cx_mch_id = 0) { $cache_key = "u_t_g_{$cx_mch_id}"; $cache_val = FlashStorage::getCache($cache_key); if($cache_val !== false){ sleep(1); $retry -= 1; return $retry >= 0 ? self::generate($type, $len, $retry, $cx_mch_id) : null; } FlashStorage::setCache($cache_key, $cache_key); $token = null; while(true){ $token = self::_generate($len); $exists = UserToken::find()->where(['type' => $type, 'token' => $token, 'is_delete' => 0, 'cx_mch_id' => $cx_mch_id])->exists(); if(!$exists){ FlashStorage::deleteCache($cache_key); break; } } return $token; } /** * 生成指定长度的token * @param integer $len 长度 */ public static function _generate($len = 12) { $chars = "qwertyuiopasdfghjklzxcvbnm1234567890MNBVCXZASDFGHJKLPIUIYTREWQ"; $max = strlen($chars) - 1; $token = ""; for($i = 0 ; $i < $len; $i++){ $start = mt_rand(0, $max); $token .= $chars[$start]; } //并发情况生成唯一token $cache_key = "u_t_n_g_no_{$token}"; $cache_val = FlashStorage::getCache($cache_key); if($cache_val !== false){ usleep(500); return self::_generate($len); } FlashStorage::setCache($cache_key, $cache_key,60); return $token; } /** * 保存token * @param string $token token * @param integer $type token类型 * @param integer $expire_time token有效时长,单位秒 * @param integer $user_id 用户ID * @param integer $cx_mch_id 平台商户ID */ public static function saveUserToken($token, $type, $expire_time, $user_id = 0, $cx_mch_id = 0) { $timestamp = time(); $model = new UserToken(); $model->cx_mch_id = $cx_mch_id; $model->type = $type; $model->token = $token; $model->user_id = $user_id; $model->expire_time = $timestamp + $expire_time; $model->status = self::STATUS_WAITING; $model->is_delete = 0; $model->created_at = $timestamp; if(!$model->save()){ return SiteHelper::getModelError($model); } return [ 'code' => 0, 'msg' => 'ok', 'data' => [ 'token' => $token ] ]; } /** * 清除已经失效的token */ public static function expiresHandler($cx_mch_id = null, $limit = 200) { $ids = UserToken::find() ->where([ 'is_delete' => 0 ]) ->andWhere([ '<', 'expire_time', time() ]) ->andFilterWhere([ 'cx_mch_id' => $cx_mch_id ]) ->select('id')->limit($limit)->column(); UserToken::updateAll(['is_delete' => 1],[ 'is_delete' => 0, 'id' => $ids ]); } public static function getOauthConf($type) { switch ($type){ //微信小程序登录 case 0: return [ 'access_token_key' => '405nr7', //@CX INIT PARAM 'refresh_token_key' => 'I0gd86', //@CX INIT PARAM 'access_token_max_age' => 60*60*24*30, //@CX INIT PARAM 'refresh_token_max_age' => 2592000, //@CX INIT PARAM 'token_len' => 12, //@CX INIT PARAM 生成token长度 'token_retry' => 3, //@CX INIT PARAM 生成token重试次数 ]; //微信公众号登录 case 1: return [ 'access_token_key' => '02LZh7', //@CX INIT PARAM 'refresh_token_key' => 'x2Ch1B', //@CX INIT PARAM 'access_token_max_age' => 7200, //@CX INIT PARAM 'refresh_token_max_age' => 2592000, //@CX INIT PARAM 'token_len' => 13, //@CX INIT PARAM 生成token长度 'token_retry' => 3, //@CX INIT PARAM 生成token重试次数 ]; //APP登录 case 2: return [ 'access_token_key' => '01LZh7', //@CX INIT PARAM 'refresh_token_key' => 'x1Ch1B', //@CX INIT PARAM 'access_token_max_age' => 7200, //@CX INIT PARAM 'refresh_token_max_age' => 2592000, //@CX INIT PARAM 'token_len' => 14, //@CX INIT PARAM 生成token长度 'token_retry' => 3, //@CX INIT PARAM 生成token重试次数 ]; //H5登录 case 3: return [ 'access_token_key' => '01LZh7', //@CX INIT PARAM 'refresh_token_key' => 'x1Ch1B', //@CX INIT PARAM 'access_token_max_age' => 86400, //@CX INIT PARAM 'refresh_token_max_age' => 2592000, //@CX INIT PARAM 'token_len' => 14, //@CX INIT PARAM 生成token长度 'token_retry' => 3, //@CX INIT PARAM 生成token重试次数 ]; //@TODO 扩展,默认微信小程序登录 default : return [ 'access_token_key' => '405nr7', //@CX INIT PARAM 'refresh_token_key' => 'I0gd86', //@CX INIT PARAM 'access_token_max_age' => 60*60*24*30, //@CX INIT PARAM 'refresh_token_max_age' => 2592000, //@CX INIT PARAM 'token_len' => 12, //@CX INIT PARAM 生成token长度 'token_retry' => 3, //@CX INIT PARAM 生成token重试次数 ]; } } public static function getTypeByPlatform($platform) { switch ($platform){ case 'wxmp': return UserToken::TYPE_WXMP_LOGIN; case 'wxoa': return UserToken::TYPE_WXOA_LOGIN; case 'app': return UserToken::TYPE_APP_LOGIN; case 'h5': return UserToken::TYPE_H5_LOGIN; //@TODO 其它平台 default : return UserToken::TYPE_WXMP_LOGIN; } } public static function destory($user_id, $type, $cx_mch_id) { UserToken::updateAll(['is_delete' => 1],[ 'is_delete' => 0, 'user_id' => $user_id, 'cx_mch_id' => $cx_mch_id, 'type' => $type ]); } }