ThinkPHP6接入阿里云短信实战:阿里云短信验证码登录
发表于:2023-02-12 00:02:49浏览:1011次
最近做的项目需要用手机号注册账号,之前没有对接过发送短信,今天研究了一下, 写下一贴以做记录。项目框架用ThinkPHP6,短信选择阿里云的短信服务。
1、首先开通阿里云短信包,之后申请短信包签名,这里大家自行去阿里云申请。
2、安装阿里云sdk,阿里云提供了两种方式安装sdk,这里选择用composer。
composer require alibabacloud/dysmsapi-20170525 2.0.9
首先创建Sample类方便调用,我们需要有短信签名,签名模板,阿里云keyId和accessKeySecret,阿里云key在阿里云首页,右上角有个acesskey管理就可以看到。
业务逻辑层生成随机验证码方法:
public static function code(){
//生成一个随机的6位数字验证码
$code = rand(11111,999999);
return $code;
}
创建验证手机号码方法:
/**
* 校验手机号码
* @param $phone
* @return bool
*/
function validatePhone ($phone) {
if(!preg_match("/^1[34578]\d{9}$/", $phone)){
return false;
}
return true;
}
控制器层验证登录
<?php
declare (strict_types = 1);
namespace app\home\controller;
use app\home\validate\UserCheck;
use avatars\MDAvatars;
use think\exception\ValidateException;
use think\facade\Db;
use think\facade\Session;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
use Darabonba\OpenApi\Models\Config;
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
class Login
{
/**
*发送短信验证码
* @return \think\Response
*/
public function send_code()
{
$param = get_params();
$type= $param['code_type'];
try {
validate(UserCheck::class)->scene($type.'code')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
//接收手机号参数
$phone= $param['mobile'];
if($type == 'reg'){
$user = Db::name('User')->where(['mobile' => $phone])->find();
if (!empty($user)) {
return to_assign(1, '该手机号已经存在');
}
}
if($type == 'forget'){
$user = Db::name('User')->where(['mobile' => $param['mobile']])->find();
if (empty($user)) {
return to_assign(1, '用户不存在');
}
if ($user['status'] == -1) {
return to_assign(1, '该用户禁止登录,请与平台联系');
}
}
//这个是验证码
$code = ['code'=>rand(111111,999999)];
$accessKeyId = get_system_config('aliyun_sms','accesskey_id');
$accessKeySecret = get_system_config('aliyun_sms','accesskey_secret');
//发短信
$client = self::createClient($accessKeyId, $accessKeySecret);
$sendSmsRequest = new SendSmsRequest([
"phoneNumbers" => $phone,
"signName" => "你的签名名称",
"templateCode" => "你的模板代号",
"templateParam" => json_encode($code)
]);
// 复制代码运行请自行打印 API 的返回值
$result = $client->sendSms($sendSmsRequest);
// var_dump($result);die;
if ($result->body->code == 'OK') {
//发送成功操作
set_cache($type.$phone, $code, 600);
return to_assign(0, '短信验证码已发送,请注意查收');
}else {
//发送失败操作
return to_assign(1, '发送失败:'.$result->body->message);
}
}
/**
* 使用AK&SK初始化账号Client
* @param string $accessKeyId
* @param string $accessKeySecret
* @return Dysmsapi Client
*/
public static function createClient($accessKeyId, $accessKeySecret){
$config = new Config([
// 您的AccessKey ID
"accessKeyId" => $accessKeyId,
// 您的AccessKey Secret
"accessKeySecret" => $accessKeySecret
]);
// 访问的域名
$config->endpoint = "dysmsapi.aliyuncs.com";
return new Dysmsapi($config);
}
//提交登录
public function login_code()
{
$param = get_params();
try {
validate(UserCheck::class)->scene('loginmobile')->check($param);
} catch (ValidateException $e) {
// 验证失败 输出错误信息
return to_assign(1, $e->getError());
}
$user = Db::name('User')->where(['mobile' => $param['mobile']])->find();
if (empty($user)) {
return to_assign(1, '用户不存在');
}
$code = get_cache('login'.$param['mobile']);
if(empty($code)){
return to_assign(1, '验证码已过期,请重新获取');
}
else{
if($code['code'] != $param['code']){
return to_assign(1, '验证码错误');
}
if ($user['status'] == -1) {
return to_assign(1, '该用户禁止登录,请与平台联系');
}
$data = [
'last_login_time' => time(),
'last_login_ip' => request()->ip(),
'login_num' => $user['login_num'] + 1,
];
Db::name('user')->where(['id' => $user['id']])->update($data);
$userInfo = [
'id' => $user['id'],
'username' => $user['username'],
'nickname' => $user['nickname'],
'headimgurl' => $user['headimgurl'],
];
$session_user = get_config('app.session_user');
Session::set($session_user, $userInfo);
$token = make_token();
set_cache($token, $userInfo, 7200);
$userInfo['token'] = $token;
//清楚验证码缓存
clear_cache('login'.$param['mobile']);
add_user_log('login', '', $user['id']);
return to_assign(0, '登录成功', $userInfo);
}
}
}
至此短信验证登录完结束
注意 最好这个代码上传到服务器验证,而且请求协议要https,否则可能会出现问题,宝塔面板可以免费申请ssl
官方文档:
获取状态的:
$result = $client->sendSms($sendSmsRequest);
// var_dump($result);die;
if ($result->body->code == 'OK') {
//发送成功操作
return to_assign(0, '发送成功');
}else {
//发送失败操作
return to_assign(1, '发送失败:'.$result->body->message);
}
推荐文章
- thinphp6如何自定义修改报错页面
- ThinkPHP6多应用多语言切换,最佳解决方案
- Layui的upload模块实现多图批量上传,无需修改代码,完美解决方案
- vue微信站history模式微信自定义分享
- 最美的国产操作系统:深度操作系统 deepin 20.5 发布
- ThinkPHP6+JS实现大文件分片上传,切片上传
- thinkphp6 leftjoin联表查询时,子表有多条记录去重后获取子表的最新记录查询方法
- 今晚新剧,碧血玄黄7/8集:金锋动,银剑现,道象阴阳变
- 开发常见的技术栈,有多程序猿能够做到全栈?
- API用户认证firebase/php-jwt,PHP使用jwt生成token