cxgj/models/UserToken.php
2023-11-27 09:45:13 +08:00

277 lines
9.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\models;
use Yii;
use app\components\FlashStorage;
use app\components\SiteHelper;
/**
* This is the model class for table "{{%user_token}}".
*
* @property int $id ID
* @property int $cx_mch_id 平台商户ID
* @property int $user_id 用户ID
* @property int $type 类型
* @property string $token 令牌
* @property int $expire_time 失效时间
* @property int $status 状态0=未验证1=验证通过2=验证未通过3=已失效
* @property int $is_delete 是否删除0=否1=是
* @property int $created_at 添加时间
*/
class UserToken extends \yii\db\ActiveRecord
{
const TYPE_WXMP_LOGIN = 0; //微信小程序登录token
const TYPE_WXOA_LOGIN = 1; //微信公众号登录token
const TYPE_APP_LOGIN = 2; //APP登录token
const TYPE_H5_LOGIN = 3; //H5登录token
const STATUS_WAITING = 0; //待验证
const STATUS_SUCCESS = 1; //验证通过
const STATUS_FAILED = 2; //验证未通过
const STATUS_VALIDATE = 3; //验证中
const STATUS_INVALID = 4; //失效
/**
* {@inheritdoc}
*/
public static function tableName()
{
return '{{%user_token}}';
}
/**
* {@inheritdoc}
*/
public function rules()
{
return [
[['cx_mch_id', 'user_id', 'type', 'expire_time', 'status', 'is_delete', 'created_at'], 'integer'],
[['token'], 'required'],
[['token'], 'string', 'max' => 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
]);
}
}