Login.php 7.58 KB
<?php

use Action\WebAction;
use LibModels\Web\Passport\RegData;
use LibModels\Web\Passport\LoginData;
use Passport\PassportModel as PassportModel;
use Configs\ChannelConfig;
use WebPlugin\Helpers;
use WebPlugin\Cache;

class LoginController extends WebAction
{

    /**
     * 登录页
     */
    public function indexAction()
    {
        $this->setTitle('用户登录');
        // 设置登录有效时间30分钟, 防机器刷
        $this->setSession('_LOGIN_EXPIRE', time() + 1800);

        //登录后跳转页面
        $getRefer = $this->get('refer');
        $httpRefer = isset($_SERVER["HTTP_REFERER"]) ? $_SERVER["HTTP_REFERER"] : '';
        $refer = $getRefer ? $getRefer : $httpRefer;
        //检查refre是否为绝对路径,补www.yohobuy.com
        if (!strstr($refer, 'http')) {
            $refer = SITE_MAIN . $refer;
        }

        if (!empty($refer)) {
            $this->setCookie('refer', $refer);
        }

        $simpleHeader = PassportModel::getSimpleHeader();
        //获取登陆页左侧资源
        $cover = PassportModel::getLeftBanner(PassportModel::SIGNIN_LEFT_BANNER_CODE);
        //整合
        $data = array(
            'loginPage' => true,
            'simpleHeader' => $simpleHeader,
            'passport' => array(
                'coverHref' => $cover['url'],
                'coverImg' => empty($cover['img']) ? ChannelConfig::$leftDefaultImg : $cover['img'],
                'countryCode' => '+86',
                'countryName' => '中国',
                'countryList' => RegData::getAreasData(),
                'forgetPwd' => Helpers::url('/passport/back/index'),
                'fastReg' => Helpers::url('/reg.html'),
                'weixinLogin' => Helpers::url('/passport/autosign/wechat'),
                'qqLogin' => Helpers::url('/passport/autosign/qq'),
                'weiboLogin' => Helpers::url('/passport/autosign/sina'),
                'alipayLogin' => Helpers::url('/passport/autosign/alipay'),
                'doubanLogin' => Helpers::url('/passport/autosign/douban'),
                'renrenLogin' => Helpers::url('/passport/autosign/renren'),
            ),
        );

        $this->_view->display('index', $data);
    }

    /**
     * 登录操作
     *
     * @param string areaCode 地区编号, 不需要+号
     * @param string account 账号(邮箱或手机号)
     * @param string password 密码
     * @return json
     */
    public function authAction()
    {
        $data = array('code' => 400, 'message' => '您输入的密码及账户名不匹配,是否<a href="' . Helpers::url('/passport/back/index') . '" target="_blank">忘记密码?</a>', 'data' => '');
        do {
            /* 判断是不是AJAX请求 */
            if (!$this->isAjax()) {
                break;
            }

            /* 判断参数是否传递 */
            $area = trim($this->post('areaCode', '86'));
            $account = trim($this->post('account'));
            $password = trim($this->post('password'));
            if (!is_numeric($area) || empty($account) || empty($password)) {
                break;
            }

            /* 判断参数是否有效 */
            $verifyEmail = Helpers::verifyEmail($account);
            $verifyMobile = ($area === '86') ? Helpers::verifyMobile($account) : Helpers::verifyAreaMobile($account, $area);
            if (!$verifyEmail && !$verifyMobile) {
                break;
            }

            /* 设置登录有效时间30分钟, 防机器刷 */
            $expire = $this->getSession('_LOGIN_EXPIRE');
            if (empty($expire) || $expire < time()) {
                $data = array('code' => 400, 'message' => '页面停留时间过长,请刷新页面', 'data' => '');
                break;
            }

            /* 购物车 */
            $shoppingKey = Helpers::getShoppingKeyByCookie();
            /*
             * 登录-防恶意机制
             * 同一用户名登录密码错误次数超10次,需30分钟后尝试
             * 同一ip登录密码错误次数超100次,需1小时后尝试 , ip错误提示语:您尝试的次数过多,账号已被暂时锁定,请稍后再试
             */
            $ip = Helpers::getClientIp();
            $ipKey = md5('ip_signin_' . $ip);
            $ipTimeKey = md5('ip_signin_time' . $ip);
            $accountKey = md5('account_signin_' . $account);
            $accountTimeKey = md5('account_signin_time' . $account);
            //cache初始化,非有效时间内清除次数,有效时间内叠加cache计数
            if (!Cache::get($accountTimeKey) && Cache::get($accountKey)) {
                Cache::delete($accountKey);
            }
            if (!Cache::get($accountTimeKey) && !Cache::get($accountKey)) {
                Cache::set($accountTimeKey, true, 1800);
                Cache::set($accountKey, 0);
            }
            if (!Cache::get($ipTimeKey) && Cache::get($ipKey)) {
                Cache::delete($ipKey);
            }
            if (!Cache::get($ipTimeKey) && !Cache::get($ipKey)) {
                Cache::set($ipTimeKey, true, 3600);
                Cache::set($ipKey, 0);
            }
            $accountTimes = Cache::get($accountKey);
            $ipTimes = Cache::get($ipKey);
            if ($accountTimes >= 10) {
                $data = array('code' => 400, 'message' => '您的账号已被暂时锁定,请稍后再试', 'data' => '');
                break;
            }
            if ($ipTimes >= 100) {
                $data = array('code' => 400, 'message' => '您尝试的次数过多,账号已被暂时锁定,请稍后再试', 'data' => '');
                break;
            }
            $data = LoginData::signin($area, $account, $password, $shoppingKey);
            if (!isset($data['code']) || $data['code'] != 200 || !isset($data['data']['uid'])) {
                Cache::set($accountKey, intval(Cache::get($accountKey)) + 1);
                Cache::set($ipKey, intval(Cache::get($ipKey)) + 1);
                $data = array('code' => 400, 'message' => '您输入的密码及账户名不匹配,是否<a href="' . Helpers::url('/passport/back/index') . '" target="_blank">忘记密码?</a>', 'data' => '');
                break;
            }

            //登录成功
            $refer = $this->getCookie('refer');
            if (empty($refer) || strstr($refer, 'signin.html') || strstr($refer, 'passport/login/index')) {
                $refer = SITE_MAIN;
            }
            else {
                $refer = rawurldecode($refer);
            }
            $data['data']['session'] = Helpers::syncUserSession($data['data']['uid'], $refer);
            $data['data']['href'] = $refer;

            $token = Helpers::makeToken($data['data']['uid']);
            $this->setCookie('_TOKEN', $token);
            $this->setSession('_TOKEN', $token);
            $this->setSession('_LOGIN_UID', $data['data']['uid']);
        }
        while (false);

        $this->echoJson($data);
    }

    //退出
    public function outAction()
    {
        // 清除服务端会话
        $this->setSession('_TOKEN', '');
        $this->setSession('_LOGIN_UID', '');

        // 清除客户端
        $this->setCookie('_UID', '');
        $this->setCookie('_TOKEN', '');
        $this->setCookie('_SPK', '');

        $refer = $this->server('HTTP_REFERER', SITE_MAIN);
        $token = $this->get('token');
        if (!empty($token)) {
            $this->go(Helpers::logoutSession($token, $refer));
        }

        $this->go($refer);
    }

}