src/AppBundle/Controller/LoginController.php line 216

Open in your IDE?
  1. <?php
  2. namespace AppBundle\Controller;
  3. use ApiBundle\Api\Exception\ErrorCode;
  4. use AppBundle\Common\ArrayToolkit;
  5. use AppBundle\Common\Exception\RuntimeException;
  6. use AppBundle\Component\OAuthClient\OAuthClientFactory;
  7. use Biz\Common\BizSms;
  8. use Biz\Sms\Service\SmsService;
  9. use Common\Exception\BizSmsException;
  10. use CorporateTrainingBundle\System;
  11. use Firebase\JWT\JWT;
  12. use Firebase\JWT\Key;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
  15. use Symfony\Component\Routing\Exception\ResourceNotFoundException;
  16. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  17. use Symfony\Component\Routing\RouterInterface;
  18. use Symfony\Component\Security\Core\Security;
  19. class LoginController extends BaseController
  20. {
  21.     public function indexAction(Request $request)
  22.     {
  23.         $_target_path $this->getTargetPath($request);
  24.         $user $this->getCurrentUser();
  25.         if ($user->isLogin()) {
  26.             return $this->createMessageResponse('info''login.message.repeat_login'null3000$_target_path);
  27.         }
  28.         $error $this->checkLoginError($request);
  29.         if ($error) {
  30.             $request->getSession()->remove(Security::AUTHENTICATION_ERROR);
  31.         } else {
  32.             $url $this->checkInviteCodeLogin($request);
  33.             if (!empty($url)) {
  34.                 return $this->redirect($url);
  35.             }
  36.         }
  37.         $this->callRemoteService($request$user);
  38.         $liveLogin $this->checkLiveLogin($request$_target_path);
  39.         return $this->render(
  40.             'login/index.html.twig',
  41.             [
  42.                 'last_username' => $request->getSession()->get(Security::LAST_USERNAME),
  43.                 'error' => $error,
  44.                 '_target_path' => $_target_path,
  45.                 'liveLogin' => $liveLogin,
  46.                 'sms_login_open' => $this->getSmsService()->isOpen(BizSms::SMS_LOGIN),
  47.             ]
  48.         );
  49.     }
  50.     protected function callRemoteService(Request $request$user)
  51.     {
  52.         if (in_array('ROLE_SUPER_ADMIN'$user['roles'])) {
  53.             $siteInfo $this->getSettingService()->get('site_info', []);
  54.             if (!empty($siteInfo) && false == $siteInfo['status']) {
  55.                 $siteInfo['applicationVersion'] = System::CT_VERSION;
  56.                 $siteInfo['domainName'] = $request->getHttpHost();
  57.                 if (empty($siteInfo['cloud_key'])) {
  58.                     $settings $this->getSettingService()->get('storage', []);
  59.                     if (!empty($settings['cloud_access_key'])) {
  60.                         $siteInfo['accessKey'] = $settings['cloud_access_key'];
  61.                         $this->postRequest('http://ct.edusoho.com/api/app_install'json_encode($siteInfo));
  62.                     }
  63.                 }
  64.             }
  65.         }
  66.     }
  67.     public function externalLoginAction(Request $requestRouterInterface $router)
  68.     {
  69.         // 新增开关校验
  70.         $setting $this->getSettingService()->get('api');
  71.         if (empty($setting['external_switch'])) {
  72.             throw new BadRequestHttpException('API设置未开启'nullErrorCode::INVALID_ARGUMENT);
  73.         }
  74.         $token $request->get('token''');
  75.         if (!$token) {
  76.             throw new BadRequestHttpException('请求参数错误'nullErrorCode::INVALID_ARGUMENT);
  77.         }
  78.         $goto $this->parseGoto($request->get('goto'''), $router);
  79.         $data JWT::decode($token, new Key($setting['api_app_secret_key'], 'HS256'));
  80.         if (empty($data) || empty($data->identifyValue) || empty($data->identifyType) || !in_array($data->identifyType, ['username''mobile''email'])) {
  81.             throw new BadRequestHttpException('请求参数错误'nullErrorCode::INVALID_ARGUMENT);
  82.         }
  83.         $user $this->getUserService()->getUserByLoginTypeAndField($data->identifyType$data->identifyValue);
  84.         if (empty($user)) {
  85.             return $this->createMessageResponse('error''external.login.message.error'null0);
  86.         }
  87.         $this->authenticateUser($user);
  88.         return $this->redirect(empty($goto) ? $this->generateUrl('homepage') : $goto);
  89.     }
  90.     protected function parseGoto(string $gotoRouterInterface $router)
  91.     {
  92.         if (empty($goto)) {
  93.             return $goto;
  94.         }
  95.         $goto urldecode($goto);
  96.         $parsedGoto parse_url($goto);
  97.         if (isset($parsedGoto['scheme']) || isset($parsedGoto['host'])) {
  98.             throw new BadRequestHttpException('跳转地址错误'nullErrorCode::INVALID_ARGUMENT);
  99.         }
  100.         $path $parsedGoto['path'] ?? '';
  101.         if (empty($path)) {
  102.             return $path;
  103.         }
  104.         try {
  105.             // 验证路径是否匹配有效路由
  106.             $router->match($path);
  107.         } catch (ResourceNotFoundException $e) {
  108.             throw new BadRequestHttpException('跳转地址无效'nullErrorCode::INVALID_ARGUMENT);
  109.         }
  110.         return $goto;
  111.     }
  112.     protected function checkLiveLogin(Request $request, &$_target_path)
  113.     {
  114.         $liveLogin preg_match('/\/live\/(.*?)\/(.*)/'$_target_path$match);
  115.         if ($liveLogin && in_array($match[2], ['login''entry''show''replay'])) {
  116.             $_target_path $this->generateUrl('live_activity_play', ['activityId' => $match[1]]);
  117.         }
  118.         return $liveLogin $match[1] : 0;
  119.     }
  120.     public function ajaxAction(Request $request)
  121.     {
  122.         $clients OAuthClientFactory::clients();
  123.         return $this->render('login/ajax.html.twig', [
  124.             '_target_path' => $this->getTargetPath($request),
  125.             'clients' => $clients,
  126.         ]);
  127.     }
  128.     public function oauth2LoginsBlockAction($targetPath$displayName true$isMayday 0)
  129.     {
  130.         $clients OAuthClientFactory::clients();
  131.         return $this->render('login/oauth2-logins-block.html.twig', [
  132.             'clients' => $clients,
  133.             'targetPath' => $targetPath,
  134.             'displayName' => $displayName,
  135.             'isMayday' => $isMayday,
  136.         ]);
  137.     }
  138.     public function smsAction(Request $request)
  139.     {
  140.         $user $this->getCurrentUser();
  141.         if ($user->isLogin()) {
  142.             return $this->createMessageResponse('info''你已经登录了'null3000$this->getTargetPath($request));
  143.         }
  144.         if ($request->isMethod('POST')) {
  145.             $mobile $request->request->get('login_mobile');
  146.             $smsToken $request->request->get('sms_token');
  147.             $smsCode $request->request->get('login_sms_code');
  148.             if (empty($mobile) || empty($smsToken) || empty($smsCode)) {
  149.                 return $this->createJsonResponse(['error' => ['message' => 'sms.code.invalid']], 400);
  150.             }
  151.             $result $this->getBizSms()->check(BizSms::SMS_LOGIN$mobile$smsToken$smsCode);
  152.             if (BizSms::STATUS_INVALID === $result) {
  153.                 return $this->createJsonResponse(['error' => ['message' => 'sms.code.invalid']], 400);
  154.             }
  155.             if (BizSms::STATUS_EXPIRED === $result) {
  156.                 return $this->createJsonResponse(['error' => ['message' => 'sms.code.expired']], 400);
  157.             }
  158.             // 按手机号获取用户,没有就注册
  159.             $user $this->getUserService()->getUserByVerifiedMobile($mobile);
  160.             if (empty($user)) {
  161.                 throw new RuntimeException('该手机账号不存在');
  162.             }
  163.             if ($user['locked']) {
  164.                 throw new RuntimeException('该用户已被封禁!');
  165.             }
  166.             $this->authenticateUser($user);
  167.             $goto $this->getTargetPath($request);
  168.             if (empty($goto) || $goto === 'undefined') {
  169.                 $goto '/';
  170.             }
  171.             return $this->createJsonResponse(['goto' => $goto]);
  172.         }
  173.         return $this->render('login/sms.html.twig', [
  174.             '_target_path' => $this->getTargetPath($request),
  175.         ]);
  176.     }
  177.     protected function checkInviteCodeLogin(Request $request)
  178.     {
  179.         if ($this->getWebExtension()->isMicroMessenger() && $this->setting('login_bind.enabled'0) && $this->setting('login_bind.weixinmob_enabled'0)) {
  180.             $inviteCode $request->query->get('inviteCode''');
  181.             return $this->generateUrl('login_bind', ['type' => 'weixinmob''_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
  182.         }
  183.         if ($this->getCTWebExtension()->isDingTalk() && $this->setting('login_bind.enabled'0) && $this->setting('login_bind.dingtalkmob_enabled'0)) {
  184.             $inviteCode $request->query->get('inviteCode''');
  185.             return $this->generateUrl('login_bind', ['type' => 'dingtalkmob''_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
  186.         }
  187.         if ($this->getCTWebExtension()->isWorkWechat() && $this->setting('login_bind.enabled'0) && $this->setting('login_bind.workwechatmob_enabled'0)) {
  188.             $inviteCode $request->query->get('inviteCode''');
  189.             return $this->generateUrl('login_bind', ['type' => 'workwechatmob''_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
  190.         }
  191.         if ($this->getCTWebExtension()->isFeiShu() && $this->setting('login_bind.enabled'0) && $this->setting('login_bind.feishumob_enabled'0)) {
  192.             $inviteCode $request->query->get('inviteCode''');
  193.             return $this->generateUrl('login_bind', ['type' => 'feishumob''_target_path' => $this->getTargetPath($request), 'inviteCode' => $inviteCode]);
  194.         }
  195.         return 0;
  196.     }
  197.     protected function getCTWebExtension()
  198.     {
  199.         return $this->container->get('corporatetrainingbundle.twig.web_extension');
  200.     }
  201.     protected function checkLoginError(Request $request)
  202.     {
  203.         if ($request->attributes->has(Security::AUTHENTICATION_ERROR)) {
  204.             return $request->attributes->get(Security::AUTHENTICATION_ERROR);
  205.         }
  206.         return $request->getSession()->get(Security::AUTHENTICATION_ERROR);
  207.     }
  208.     protected function checkSmsCode(Request $request)
  209.     {
  210.         $fields $request->request->all();
  211.         if (!ArrayToolkit::requireds($fields, ['login_mobile''sms_token''login_sms_code'])) {
  212.             return false;
  213.         }
  214.         $result $this->getBizSms()->checkAndGetMessage(
  215.             BizSms::SMS_LOGIN,
  216.             $fields['login_mobile'],
  217.             $fields['sms_token'],
  218.             $fields['login_sms_code']
  219.         );
  220.         return $result['success'];
  221.     }
  222.     protected function getSmsCodeErrorMessage($result)
  223.     {
  224.         if ($result['success']) {
  225.             return null;
  226.         }
  227.         return $result['message'];
  228.     }
  229.     /**
  230.     protected function getTargetPath(Request $request)
  231.     {
  232.         if ($request->query->get('goto')) {
  233.             $targetPath = $request->query->get('goto');
  234.         } elseif ($request->getSession()->has('_target_path')) {
  235.             $targetPath = $request->getSession()->get('_target_path');
  236.         } elseif ($request->request->get('_target_path')) {
  237.             $targetPath = $request->request->get('_target_path');
  238.         } else {
  239.             $targetPath = $request->headers->get('Referer', '');
  240.         }
  241.         if (empty($targetPath)) {
  242.             return $this->generateUrl('homepage');
  243.         }
  244.         if ($targetPath == $this->generateUrl('login', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
  245.             return $this->generateUrl('homepage');
  246.         }
  247.         $url = explode('?', $targetPath);
  248.         if ($url[0] == $this->generateUrl('partner_logout', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
  249.             return $this->generateUrl('homepage');
  250.         }
  251.         if ($url[0] == $this->generateUrl('password_reset_update', [], UrlGeneratorInterface::ABSOLUTE_URL)) {
  252.             $targetPath = $this->generateUrl('homepage', [], UrlGeneratorInterface::ABSOLUTE_URL);
  253.         }
  254.         if (0 === strpos($targetPath, '/app.php')) {
  255.             $targetPath = str_replace('/app.php', '', $targetPath);
  256.         }
  257.         return $targetPath;
  258.     }
  259.     protected function getWebExtension()
  260.     {
  261.         return $this->container->get('web.twig.extension');
  262.     }
  263.     /**
  264.      * @return BizSms
  265.      */
  266.     protected function getBizSms()
  267.     {
  268.         $biz $this->getBiz();
  269.         return $biz['biz_sms'];
  270.     }
  271.     protected function getSettingService()
  272.     {
  273.         return $this->container->get('biz')->service('System:SettingService');
  274.     }
  275.     /**
  276.      * @return SmsService
  277.      */
  278.     protected function getSmsService()
  279.     {
  280.         return $this->getBiz()->service('Sms:SmsService');
  281.     }
  282. }