1、验证码发送
调用 Sms 中的 send
/**
* 调用 Sms 中的 send
*
* @param string $mobile 手机号
* @param string $event 事件
*/
public function code(){
$mobile = $this->request->request('mobile');
$event = $this->request->request('event');
if (!$mobile || !$event) {
$this->error(__('手机号、事件不能为空'));
}
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号不正确'));
}
$code = Sms::send($mobile,$code = null, $event);
if ($code) {
$this->success(__('验证码发送成功'));
} else {
//$this->success(__('验证码发送失败'));
$this->error(__('验证码发送失败'));
}
}
Sms 中的 send
/**
* 发送验证码
*
* @param int $mobile 手机号
* @param int $code 验证码,为空时将自动生成4位数字
* @param string $event 事件
* @return boolean
*/
public static function send($mobile, $code = null, $event = 'default')
{
$code = is_null($code) ? mt_rand(1000, 9999) : $code;
$time = time();
$ip = request()->ip();
$sms = \app\common\model\Sms::create(['event' => $event, 'mobile' => $mobile, 'code' => $code, 'ip' => $ip, 'createtime' => $time]);
$result = Hook::listen('sms_send', $sms, null, true);
if (!$result) {
$sms->delete();
return false;
}
return true;
}
Hook 中的 listen
/**
* 监听标签的行为
* @access public
* @param string $tag 标签名称
* @param mixed $params 传入参数
* @param mixed $extra 额外参数
* @param bool $once 只获取一个有效返回值
* @return mixed
*/
public static function listen($tag, &$params = null, $extra = null, $once = false)
{
$results = [];
foreach (static::get($tag) as $key => $name) {
$results[$key] = self::exec($name, $tag, $params, $extra);
// 如果返回 false,或者仅获取一个有效返回则中断行为执行
if (false === $results[$key] || (!is_null($results[$key]) && $once)) {
break;
}
}
return $once ? end($results) : $results;
}
(1)sms数据库
CREATE TABLE `zt_sms` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`event` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '事件',
`mobile` varchar(20) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '手机号',
`code` varchar(10) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '验证码',
`times` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '验证次数',
`ip` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'IP',
`createtime` int(10) unsigned DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=141 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT COMMENT='短信验证码表';
2、用户注册
/**
* 用户注册
*
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param string $code 验证码
*/
public function register()
{
$username = $this->request->request('username');
$password = $this->request->request('password');
$email = $this->request->request('email');
$mobile = $this->request->request('mobile');
$code = $this->request->request('code');
if (!$username || !$password) {
$this->error(__('用户名、密码不能为空'));
}
if ($email && !Validate::is($email, "email")) {
$this->error(__('邮箱格式错误'));
}
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
$this->error(__('手机号格式错误'));
}
$ret = Sms::check($mobile, $code, 'register');
if (!$ret) {
$this->error(__('验证码不正确'));
}
$ret = $this->auth->register($username, $password, $email, $mobile, []);
if ($ret) {
$data = ['userinfo' => $this->auth->getUserinfo()];
$this->success(__('注册成功'), $data);
} else {
$this->error($this->auth->getError());
}
}
Sms 中的 check
/**
* 校验验证码
*
* @param int $mobile 手机号
* @param int $code 验证码
* @param string $event 事件
* @return boolean
*/
public static function check($mobile, $code, $event = 'default')
{
$time = time() - self::$expire;
$sms = \app\common\model\Sms::where(['mobile' => $mobile, 'event' => $event])
->order('id', 'DESC')
->find();
if ($sms) {
if ($sms['createtime'] > $time && $sms['times'] <= self::$maxCheckNums) {
$correct = $code == $sms['code'];
if (!$correct) {
$sms->times = $sms->times + 1;
$sms->save();
return false;
} else {
$result = Hook::listen('sms_check', $sms, null, true);
return $result;
}
} else {
// 过期则清空该手机验证码
self::flush($mobile, $event);
return false;
}
} else {
return false;
}
}
Auth 中的 register
/**
* 注册用户
*
* @param string $username 用户名
* @param string $password 密码
* @param string $email 邮箱
* @param string $mobile 手机号
* @param array $extend 扩展参数
* @return boolean
*/
public function register($username, $password, $email = '', $mobile = '', $extend = [])
{
// 检测用户名、昵称、邮箱、手机号是否存在
if (User::getByUsername($username)) {
$this->setError('用户名已存在');
return false;
}
if (User::getByNickname($username)) {
$this->setError('昵称已存在');
return false;
}
if ($email && User::getByEmail($email)) {
$this->setError('邮箱已存在');
return false;
}
if ($mobile && User::getByMobile($mobile)) {
$this->setError('手机号已存在');
return false;
}
$ip = request()->ip();
$time = time();
$data = [
'username' => $username,
'password' => $password,
'email' => $email,
'mobile' => $mobile,
'level' => 1,
'score' => 0,
'avatar' => '',
];
$params = array_merge($data, [
'nickname' => preg_match("/^1[3-9]{1}\d{9}$/",$username) ? substr_replace($username,'****',3,4) : $username,
'salt' => Random::alnum(),
'jointime' => $time,
'joinip' => $ip,
'logintime' => $time,
'loginip' => $ip,
'prevtime' => $time,
'status' => 'normal'
]);
$params['password'] = $this->getEncryptPassword($password, $params['salt']);
$params = array_merge($params, $extend);
//账号注册时需要开启事务,避免出现垃圾数据
Db::startTrans();
try {
$user = User::create($params, true);
$this->_user = User::get($user->id);
//设置Token
$this->_token = Random::uuid();
Token::set($this->_token, $user->id, $this->keeptime);
//设置登录状态
$this->_logined = true;
//注册成功的事件
Hook::listen("user_register_successed", $this->_user, $data);
Db::commit();
} catch (Exception $e) {
$this->setError($e->getMessage());
Db::rollback();
return false;
}
return true;
}
(2)user数据库
CREATE TABLE `zt_user` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`group_id` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '组别ID',
`username` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '用户名',
`nickname` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '昵称',
`password` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '密码',
`salt` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '密码盐',
`ali_pay` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '支付宝账号',
`true_name` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '真实姓名',
`email` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '电子邮箱',
`mobile` varchar(11) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '手机号',
`avatar` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '头像',
`level` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '等级',
`gender` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '性别',
`birthday` date DEFAULT NULL COMMENT '生日',
`bio` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '格言',
`money` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '余额',
`score` int(10) NOT NULL DEFAULT '0' COMMENT '积分',
`successions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '连续登录天数',
`maxsuccessions` int(10) unsigned NOT NULL DEFAULT '1' COMMENT '最大连续登录天数',
`prevtime` int(10) DEFAULT NULL COMMENT '上次登录时间',
`logintime` int(10) DEFAULT NULL COMMENT '登录时间',
`loginip` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '登录IP',
`loginfailure` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '失败次数',
`joinip` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '加入IP',
`jointime` int(10) DEFAULT NULL COMMENT '加入时间',
`createtime` int(10) DEFAULT NULL COMMENT '创建时间',
`updatetime` int(10) DEFAULT NULL COMMENT '更新时间',
`token` varchar(50) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT 'Token',
`status` varchar(30) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '状态',
`verification` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '验证',
PRIMARY KEY (`id`),
KEY `username` (`username`),
KEY `email` (`email`),
KEY `mobile` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT COMMENT='会员表';