Browse Source

登录优化

zhangdehua 1 year ago
parent
commit
22ad3df0c7

+ 1 - 1
app/index/controller/Captcha.php

@@ -14,7 +14,7 @@ namespace app\index\controller;
 
 use app\index\service\passport\MailCaptcha;
 use think\response\Json;
-use app\api\service\passport\{Captcha as CaptchaService,
+use app\index\service\passport\{Captcha as CaptchaService,
     MailCaptcha as MailCaptchaService,
     SmsCaptcha as SmsCaptchaService};
 use cores\exception\BaseException;

+ 1 - 1
app/index/controller/Checkout.php

@@ -156,7 +156,7 @@ class Checkout extends Controller
         // 购物车商品列表
         $goodsList = $CartModel->getOrderGoodsList($cartIds);
         if (empty($goodsList)) {
-            return $this->renderError('请选择商品结算');
+            return $this->renderError('Please add items to your shopping cart first');
         }
         // 获取订单结算信息
         $orderInfo = $Checkout->onCheckout($goodsList);

+ 20 - 9
app/index/controller/Passport.php

@@ -33,20 +33,20 @@ class Passport extends Controller
      */
     public function login()
     {
-        if ($this->request->method() =='GET'){
+        if ($this->request->method() == 'GET') {
             return view('logIn');
         }
         // 执行登录
         $LoginService = new LoginService;
-        if (!$LoginService->login($this->postForm())) {
+        if (!$LoginService->toLogin($this->postForm())) {
             return $this->renderError($LoginService->getError());
         }
         // 用户信息
         $userInfo = $LoginService->getUserInfo();
         $token = $LoginService->getToken((int)$userInfo['user_id']);
 
-        Session::set('access_token',$token);
-        Session::set('user_id',$userInfo['user_id']);
+        Session::set('access_token', $token);
+        Session::set('user_id', $userInfo['user_id']);
 
         return $this->renderSuccess([
             'userId' => (int)$userInfo['user_id'],
@@ -54,6 +54,17 @@ class Passport extends Controller
         ], '登录成功');
     }
 
+    public function register()
+    {
+        // 执行登录
+        $LoginService = new LoginService;
+        if (!$LoginService->toRegister($this->postForm())) {
+            return $this->renderError($LoginService->getError());
+        }
+
+        return $this->renderSuccess([], 'Registration is successful');
+    }
+
     /**
      * 退出登录
      * @return \think\response\View
@@ -67,19 +78,19 @@ class Passport extends Controller
 
     public function retrievePassword()
     {
-        if ($this->request->method() =='GET'){
+        if ($this->request->method() == 'GET') {
             return view('retrievePassword');
         }
 
         $params = $this->postForm();
-        if (empty($params['mobile']) || empty($params['smsCode'])){
-            if ($params['password'] !== $params['password1']){
+        if (empty($params['mobile']) || empty($params['smsCode'])) {
+            if ($params['password'] !== $params['password1']) {
                 return $this->renderError('password not match');
             }
         }
         $LoginService = new LoginService;
-        $r = $LoginService->resetPassword($params['mobile'],$params['smsCode'],$params['password']);
-        if ($r){
+        $r = $LoginService->resetPassword($params['mobile'], $params['smsCode'], $params['password']);
+        if ($r) {
             return $this->renderSuccess([], 'Reset success');
         }
         return $this->renderError('something wrong');

+ 33 - 0
app/index/service/passport/Captcha.php

@@ -0,0 +1,33 @@
+<?php
+// +----------------------------------------------------------------------
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
+// +----------------------------------------------------------------------
+// | Author: 萤火科技 <admin@yiovo.com>
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\index\service\passport;
+
+use app\common\service\BaseService;
+use yiovo\captcha\facade\CaptchaApi;
+
+class Captcha extends BaseService
+{
+    /**
+     * 图形验证码
+     * @return array
+     */
+    public function create(): array
+    {
+        $data = CaptchaApi::create();
+        return [
+            'base64' => str_replace("\r\n", '', $data['base64']),
+            'key' => $data['key'],
+            'md5' => $data['md5']
+        ];
+    }
+}

+ 56 - 8
app/index/service/passport/Login.php

@@ -15,9 +15,9 @@ namespace app\index\service\passport;
 use think\facade\Cache;
 use think\helper\Str;
 use yiovo\captcha\facade\CaptchaApi;
-use app\api\model\{User as UserModel, Setting as SettingModel};
-use app\api\service\{user\Oauth as OauthService, user\Avatar as AvatarService, passport\Party as PartyService};
-use app\api\validate\passport\Login as ValidateLogin;
+use app\index\model\{User as UserModel, Setting as SettingModel};
+use app\index\service\{user\Oauth as OauthService, user\Avatar as AvatarService, passport\Party as PartyService};
+use app\index\validate\passport\Login as ValidateLogin;
 use app\common\service\BaseService;
 use app\common\enum\Setting as SettingEnum;
 use cores\exception\BaseException;
@@ -51,9 +51,9 @@ class Login extends BaseService
     public function login(array $data): bool
     {
         empty($data['partyData']) && $data['partyData'] = [];
-        if ($data['isParty'] == 'true' || $data['isParty'] === true){
+        if ($data['isParty'] == 'true' || $data['isParty'] === true) {
             $data['isParty'] = true;
-        }else{
+        } else {
             $data['isParty'] = false;
         }
 
@@ -67,6 +67,54 @@ class Login extends BaseService
         return $this->setSession();
     }
 
+
+    public function toLogin(array $data): bool
+    {
+        empty($data['partyData']) && $data['partyData'] = [];
+        if ($data['isParty'] == 'true' || $data['isParty'] === true) {
+            $data['isParty'] = true;
+        } else {
+            $data['isParty'] = false;
+        }
+
+        // 数据验证
+        $this->validate($data);
+        // 自动登录注册
+        $userInfo = UserModel::detail(['mobile' => $data['mobile']]);
+        if ($userInfo) {
+            if (md5($data['password'] . $userInfo['salt']) !== $userInfo['password']) {
+                throwError('The account does not exist or the password is incorrect.', 500, []);
+            }
+
+            $this->updateUser($userInfo, $data['isParty'], $data['partyData']);
+            // 保存第三方用户信息
+            $this->createUserOauth($this->getUserId(), $data['isParty'], $data['partyData']);
+            // 记录登录态
+            return $this->setSession();
+        } else {
+            throwError('The account does not exist or the password is incorrect.', 500, []);
+        }
+    }
+
+    public function toRegister(array $data): bool
+    {
+        empty($data['partyData']) && $data['partyData'] = [];
+        if ($data['isParty'] == 'true' || $data['isParty'] === true) {
+            $data['isParty'] = true;
+        } else {
+            $data['isParty'] = false;
+        }
+        // 数据验证
+        $this->validate($data);
+        $userInfo = UserModel::detail(['mobile' => $data['mobile']]);
+        if ($userInfo) {
+            throwError('The account you entered has already been registered.', 500, []);
+        }
+        // 用户不存在: 创建一个新用户
+        $this->createUser($data['mobile'], $data['isParty'], $data['partyData'], $data['password']);
+        return true;
+    }
+
     /**
      * 快捷登录:微信小程序用户
      * @param array $form
@@ -112,14 +160,14 @@ class Login extends BaseService
         return $this->setSession();
     }
 
-    public function resetPassword($email,$smsCode,$password)
+    public function resetPassword($email, $smsCode, $password)
     {
         //todo 电子烟校验邮箱mobile的验证码是否匹配
         $mailCaptcha = new MailCaptcha();
         $mailCaptcha->checkCaptcha($smsCode, $email);
 
-        $userInfo = !empty($email) ? UserModel::detail(['mobile'=>$email]) : null;
-        if (empty($userInfo)){
+        $userInfo = !empty($email) ? UserModel::detail(['mobile' => $email]) : null;
+        if (empty($userInfo)) {
             throwError('Not exit', 401, []);
         }
 

+ 11 - 8
app/index/service/passport/MailCaptcha.php

@@ -46,7 +46,7 @@ class MailCaptcha extends BaseService
         // 数据验证
         $this->validate($data);
         // 执行发送短信
-        if (!$this->sendCaptcha($data['email'])) {
+        if (!$this->sendCaptcha($data['mobile'])) {
             return false;
         }
         return true;
@@ -67,6 +67,7 @@ class MailCaptcha extends BaseService
         $smsCaptcha = CaptchaApi::createSMS($email);
 
         $mail = new PHPMailer(true);
+        //dd(config('smtp'));
         try {
             //Server settings
             $mail->SMTPDebug = SMTP::DEBUG_OFF;//DEBUG_OFF,DEBUG_SERVER           //Enable verbose debug output
@@ -78,16 +79,16 @@ class MailCaptcha extends BaseService
                 )
             );
             $mail->isSMTP();                                            //Send using SMTP
-            $mail->Host = 'smtp.163.com';                     //Set the SMTP server to send through
+            $mail->Host = config('smtp.host');                     //Set the SMTP server to send through
             $mail->SMTPAuth = true;                                   //Enable SMTP authentication
-            $mail->Username = 'zhangdehua814@163.com';                     //SMTP username
-            $mail->Password = 'SGPMIQCKVKGIJUGQ';                               //SMTP password
+            $mail->Username = config('smtp.username');                   //SMTP username
+            $mail->Password = config('smtp.password');                               //SMTP password
             $mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;            //Enable implicit TLS encryption
-            $mail->Port = 465;                                    //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
+            $mail->Port = config('smtp.port');                                    //TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS`
 
             //Recipients
-            $mail->setFrom('zhangdehua814@163.com', 'Mailer');
-            $mail->addAddress($email, 'Gold');     //Add a recipient
+            $mail->setFrom(config('smtp.from_address'), config('smtp.from_name'));
+            $mail->addAddress($email, 'FSV');     //Add a recipient
             //$mail->addAddress('ellen@example.com');               //Name is optional
             //$mail->addReplyTo('info@example.com', 'Information');
             //$mail->addCC('cc@example.com');
@@ -207,7 +208,9 @@ class MailCaptcha extends BaseService
 
     public function checkCaptcha($captchaCode = '', $email = '')
     {
-        if ($captchaCode == '888888'){ return true;}
+        if ($captchaCode == '888888') {
+            return true;
+        }
         $localCode = Cache::get('captchaSMS.' . $email);
         if (empty($localCode) || empty($localCode['code']) || $localCode['code'] != $captchaCode) {
             throwError('Sorry,your captcha is invalid');

+ 114 - 0
app/index/service/passport/SmsCaptcha.php

@@ -0,0 +1,114 @@
+<?php
+// +----------------------------------------------------------------------
+// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
+// +----------------------------------------------------------------------
+// | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
+// +----------------------------------------------------------------------
+// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
+// +----------------------------------------------------------------------
+// | Author: 萤火科技 <admin@yiovo.com>
+// +----------------------------------------------------------------------
+declare (strict_types=1);
+
+namespace app\index\service\passport;
+
+use yiovo\cache\facade\Cache;
+use yiovo\captcha\facade\CaptchaApi;
+use app\api\validate\passport\SmsCaptcha as ValidateSmsCaptcha;
+use app\common\service\BaseService;
+use app\common\service\Message as MessageService;
+use cores\exception\BaseException;
+
+/**
+ * 服务类:发送短信验证码
+ * Class SmsCaptcha
+ * @package app\index\service\passport
+ */
+class SmsCaptcha extends BaseService
+{
+    // 最大发送次数,默认10次
+    protected $sendTimes = 10;
+
+    // 发送限制间隔时间,默认24小时
+    protected $safeTime = 86400;
+
+    /**
+     * 发送短信验证码
+     * @param array $data
+     * @return bool
+     * @throws BaseException
+     */
+    public function handle(array $data): bool
+    {
+        // 数据验证
+        $this->validate($data);
+        // 执行发送短信
+        if (!$this->sendCaptcha($data['mobile'])) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * 执行发送短信
+     * @param string $mobile
+     * @return bool
+     */
+    private function sendCaptcha(string $mobile): bool
+    {
+        // 缓存发送记录并判断次数
+        if (!$this->record($mobile)) {
+            return false;
+        }
+        // 生成验证码
+        $smsCaptcha = CaptchaApi::createSMS($mobile);
+        // 发送短信
+        MessageService::send('passport.captcha', [
+            'code' => $smsCaptcha['code'],
+            'mobile' => $smsCaptcha['key']
+        ], $this->storeId);
+        return true;
+    }
+
+    /**
+     * 记录短信验证码发送记录并判断是否超出发送限制
+     * @param string $mobile
+     * @return bool
+     */
+    private function record(string $mobile): bool
+    {
+        // 获取发送记录缓存
+        $record = Cache::get("sendCaptchaSMS.$mobile");
+        // 写入缓存:记录剩余发送次数
+        if (empty($record)) {
+            Cache::set("sendCaptchaSMS.$mobile", ['times' => $this->sendTimes - 1], $this->safeTime);
+            return true;
+        }
+        // 判断发送次数是否合法
+        if ($record['times'] <= 0) {
+            $this->error = '很抱歉,已超出今日最大发送次数限制';
+            return false;
+        }
+        // 发送次数递减
+        Cache::update("sendCaptchaSMS.$mobile", ['times' => $record['times'] - 1]);
+        return true;
+    }
+
+    /**
+     * 数据验证
+     * @param array $data
+     * @throws BaseException
+     */
+    private function validate(array $data)
+    {
+        // 数据验证
+        $validate = new ValidateSmsCaptcha;
+        if (!$validate->check($data)) {
+            throwError($validate->getError());
+        }
+        // 验证图形验证码
+        if (!CaptchaApi::check($data['captchaCode'], $data['captchaKey'])) {
+            throwError('很抱歉,图形验证码不正确');
+        }
+    }
+}

+ 1 - 0
app/index/view/cart/shoppingCart.html

@@ -550,6 +550,7 @@
                 window.location.replace('../passport/logIn.html')
             } else {
                 showToast(message)
+                $("#loadingModel").hide(0)
             }
         });
 

+ 24 - 21
app/index/view/passport/logIn.html

@@ -14,7 +14,7 @@
     <meta name="apple-mobile-web-app-capable" content="yes"/>
     <meta name="keywords" content="电子烟,关键字"/>
     <meta name="Description" content="网站描述"/>
-    <title>登录|注册</title>
+    <title>Log in|Register</title>
     <link rel="stylesheet" href="/assets/index/css/common.css?t=10100">
     <link rel="stylesheet" href="/assets/index/css/login.css?t=101">
 </head>
@@ -40,13 +40,14 @@
                         <p class="miTitle">Password</p>
                         <input class="input" type="password" name="" id="password">
                     </div>
-                    <a href="/index/passport/retrievePassword.html"><p class="forgotPassword">Forget Your Password?</p></a>
+                    <a href="/index/passport/retrievePassword.html"><p class="forgotPassword">Forget Your Password?</p>
+                    </a>
                     <!-- 登录 -->
                     <div class="pageButton" id="loginButton">Login</div>
                     <!-- 没有账户 -->
                     <div class="accountTips">
                         <p>No account?</p>
-                        <span id="toRegister">Regist</span>
+                        <span id="toRegister">Register</span>
                     </div>
                 </div>
             </div>
@@ -189,7 +190,7 @@
 
             $.ajax({
                 url: "/index/passport/login",
-                headers: {platform: 'H5',storeId:10001},
+                headers: {platform: 'H5', storeId: 10001},
                 dataType: 'json',
                 data: JSON.stringify(dp),
                 type: "POST",
@@ -199,9 +200,12 @@
                     //return false;
                     //注册成功后进入
                     if (obj.status === 200 || obj.status === '200') {
-                        console.log("success",obj.data.token)
-                        localStorage.setItem(VAPES_TOKEN, obj.data.token)
-                        jumpPage()
+                        showToast('Login successful')
+                        setTimeout(function () {
+                            jumpPage()
+                        }, 2000)
+                    } else {
+                        showToast(obj.message)
                     }
 
                 }
@@ -251,7 +255,7 @@
                         //parentElement.siblings().hide(0)
                         $("#emailVerifyModel").show(0).siblings().hide(0)
                         $("#emailAddress").text(email)
-                    }else {
+                    } else {
                         showToast('Please try again later.')
                     }
                 }
@@ -278,8 +282,8 @@
             const email = emailEle.val()
 
             const dp = {
-                    mobile: email,
-                    smsCode: vcode,
+                mobile: email,
+                smsCode: vcode,
             };
 
             $.ajax({
@@ -298,7 +302,7 @@
                         //parentElement.hide(0)
                         //parentElement.siblings().hide(0)
                         $("#setPasswordModel").show(0).siblings().hide(0)
-                    }else {
+                    } else {
                         showToast('Please try again later.')
                     }
                 }
@@ -331,27 +335,26 @@
             }
 
             $.ajax({
-                url: "/index/passport/login",
+                url: "/index/passport/register",
                 headers: {platform: 'H5'},
                 dataType: 'json',
                 data: JSON.stringify(dp),
                 type: "POST",
                 contentType: 'application/json',
                 success: function (obj) {
-                    console.log(obj);
-                    //return false;
                     //注册成功后进入
                     if (obj.status === 200 || obj.status === '200') {
-                        console.log("注册成功",obj.data.token)
-                        localStorage.setItem(VAPES_TOKEN, obj.data.token)
-                        jumpPage()
+                        // console.log("注册成功",obj.data.token)
+                        // localStorage.setItem(VAPES_TOKEN, obj.data.token)
+                        showToast('Register successful')
+                        setTimeout(function () {
+                            jumpPage()
+                        }, 2000)
+                    } else {
+                        showToast(obj.message)
                     }
-
                 }
-
             })
-
-
         })
 
         function jumpPage() {

+ 18 - 0
config/smtp.php

@@ -0,0 +1,18 @@
+<?php
+// +----------------------------------------------------------------------
+// | Smtp邮件服务配置
+// +----------------------------------------------------------------------
+return [
+    // 服务器
+    'host' => env('smtp.server', 'smtp.163.com'),
+    // 账号
+    'username' => env('smtp.username', 'zhangdehua814@163.com'),
+    // 密码
+    'password' => env('smtp.password', 'SGPMIQCKVKGIJUGQ'),
+    //  cookie 启用安全传输
+    'port' => env('smtp.port', 465),
+    // 发送人邮箱
+    'from_address' => env('smtp.from_address', 'zhangdehua814@163.com'),
+    // 发送人名称
+    'from_name' => env('smtp.from_name', 'zhangdehua814@163.com'),
+];