| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- <?php
- /**
- * 描述.
- *
- * @author nj
- * @date 2021-05-18 20:38:13
- */
- namespace Modules\AgentApi\Controllers;
- use App\Repositories\AgentLogRepository;
- use App\Repositories\AgentRepository;
- use App\Repositories\Utils\JwtRepository;
- use Modules\AgentApi\Services\AgentAuthService;
- use Validator;
- use Lcobucci\JWT\Token;
- use Otp\Otp;
- use Otp\GoogleAuthenticator;
- use ParagonIE\ConstantTime\Encoding;
- class AuthController extends BaseController
- {
- /**
- * Jwt受众.
- *
- * @var string
- */
- private $jwtAud = 'agent-users';
- /**
- * 属性描述.
- *
- * @var AgentLogRepository
- */
- protected $logRepo = null;
- public function login()
- {
- $inputData = $this->getJsonData();
- /**
- * @var Validator $validatorFactory
- */
- $validatorFactory = app('validator');
- /**
- * @var AgentRepository $agentRepo
- */
- $agentRepo = app(AgentRepository::class);
- /**
- * @var AgentAuthService $authService
- */
- $authService = app(AgentAuthService::class);
- $rules = [
- 'username' => 'required|max:64',
- 'password' => 'required|max:64',
- // 'verify' => 'required|max:12',
- // 'captcha_key' => 'required',
- 'ggcode' => 'nullable|max:10',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- // if (!captcha_api_check($inputData['verify'], $inputData['captcha_key'], 'sanguo')) {
- // return json_fail('验证码有误.');
- // }
- // 查询字段.
- $columns = [
- 'id', 'uid', 'username', 'nick', 'password', 'salt', 'last_login_at', 'otp_secret', 'status',
- ];
- // 条件.
- $conditions = ['username' => $inputData['username']];
- $agents = $agentRepo->findWhere($conditions, $columns);
- // 先判断是否存在用户.
- if ($agents->count() == 0) {
- $logSubject = '代理登陆获取token失败;原因:无此账号;入参:account['. $inputData['username'] .'];密码:['. pass_encode($inputData['password']) .']';
- $logSvalue = '';
- $logDbData = [];
- $this->log($logSubject, $logSvalue, $logDbData);
- // 给一个不容易分析的错误信息给前台.
- return json_fail('代理账号或者密码错误.');
- }
- // 取第一个用户.
- $agent = $agents->first();
- $md5password = $agentRepo->generatePassword($inputData['password'], $agent->salt);
- if ($agent->password !== $md5password) {
- $logSubject = '代理登陆获取token失败;原因:密码错误;入参:account['. $inputData['username'] .'];密码:['. pass_encode($inputData['password']) .']';
- $logSvalue = '';
- $logDbData = [];
- $this->log($logSubject, $logSvalue, $logDbData);
- return json_fail('账号或者密码错误.');
- }
- $ggcode = isset($inputData['ggcode']) ? $inputData['ggcode'] : '';
- $isOpenOtp = boolval(env('OTP_OPEN', true)); //是否开启谷歌身份码验证功能
- if ($isOpenOtp) {
- if (empty($ggcode)) {
- return json_fail('请填写身份码.');
- }
- $otp = new Otp();
- $otpSecret = !empty($agent->otp_secret) ? $agent->otp_secret : GoogleAuthenticator::generateRandom();
- $otpCheckResult = $otp->checkTotp(Encoding::base32DecodeUpper($otpSecret), $ggcode);
- if (!$otpCheckResult) {
- $logSubject = '代理登陆获取token失败;原因:OTP错误;入参:用户名['. $inputData['username'] .'];密码:['. pass_encode($inputData['password']) .'];otp:['. pass_encode($ggcode) .']';
- $logSvalue = '';
- $logDbData = [];
- $this->log($logSubject, $logSvalue, $logDbData);
- return json_fail('身份码不正确');
- }
- }
- if ($agent->status == 2) {
- $logSubject = '代理登陆获取token失败;原因:被冻结;入参:username['. $inputData['username'] .'];密码:['. pass_encode($inputData['password']) .']';
- $logSvalue = '';
- $logDbData = [];
- $this->log($logSubject, $logSvalue, $logDbData);
- return json_fail('您已经被冻结,无法登陆.');
- }
- $logSubject = '登录成功';
- $logSvalue = $agent->uid;
- list($module, $action) = $this->getModuleAndAction();
- $inputs = [
- 'agent_uid' => $agent->uid,
- 'username' => $agent->username,
- 'nick' => $agent->nick,
- 'subject' => mb_strcut($logSubject, 0, 700),
- 'module' => $module,
- 'action' => $action,
- 'svalue' => !empty($logSvalue) ? $logSvalue : '',
- 'db_data' => [],
- ];
- $this->getLogRepo()->createOne($inputs);
- $tokenInfo = $authService->createSingleJwt($agent->uid);
- app(AgentRepository::class)->update(['last_login_ip' => request()->ip(), 'last_login_at' => date('Y-m-d H:i:s')], $agent->uid, 'uid');
- $data = [
- 'token' => $tokenInfo['token'],
- 'expired_at' => $tokenInfo['expired_at'],
- 'agent_uid' => $agent->uid,
- ];
- return json_success($data);
- }
- public function logout()
- {
- }
- /**
- * 刷新Token并返回token.
- * @param mixed $validatorFactory
- * @param JwtRepository $jwtRepository
- * @param AgentAuthService $authService
- * @return mixed
- * @throws \Psr\SimpleCache\InvalidArgumentException
- */
- public function refreshToken() {
- /**
- * @var Validator $validatorFactory
- */
- $validatorFactory = app('validator');
- /**
- * @var AgentRepository $agentRepo
- */
- $agentRepo = app(AgentRepository::class);
- /**
- * @var AgentAuthService $authService
- */
- $authService = app(AgentAuthService::class);
- /**
- * @var JwtRepository $jwtRepository
- */
- $jwtRepository = app(JwtRepository::class);
- $inputData = $this->getJsonData();
- $rules = [
- 'agent_uid' => 'required',
- 'old_token' => 'required',
- ];
- $validator = $validatorFactory->make($inputData, $rules);
- if ($validator->fails()) {
- // 如果有错误(可能是多个信息),这里只取第一个错误信息返回.
- return json_fail($validator->errors()->first());
- }
- $validateResult = $jwtRepository->validateToken($inputData['old_token'], $this->jwtAud);
- if ($validateResult['is_illegal']) {
- return json_fail('无效数据传入.');
- }
- if (!$validateResult['is_valid']) {
- return json_fail('旧Token无效.');
- }
- /*if (!$validateResult['is_expired']) {
- // 旧token没过期
- return json_fail('旧token怎么了');
- }*/
- /**
- * @var Token $tokenObj
- */
- $tokenObj = $validateResult['token_obj'];
- $claims = $tokenObj->claims();
- $agentUid = $claims->get('agent_uid');
- // 检查入参设备信息是否有效.
- if ($agentUid != $inputData['agent_uid']) {
- $logSubject = '代理登陆刷新token失败;原因:入参agent_uid和token中的agent_uid不一致;入参:agent_uid['. $inputData['agent_uid'] .']';
- $logSvalue = '';
- $logDbData = [];
- $this->log($logSubject, $logSvalue, $logDbData);
- return json_fail('无效数据匹配.');
- }
- $tokenInfo = $authService->createSingleJwt($agentUid);
- $data = [
- 'token' => $tokenInfo['token'],
- 'expired_at' => $tokenInfo['expired_at'],
- ];
- return json_success($data);
- }
- /**
- * php ping
- * @return string
- */
- public function ping()
- {
- return 'pong';
- }
- public function captchaImage()
- {
- return captcha('sanguo');
- }
- /**
- * 记录操作日志.
- * @param string $subject 主题.
- * @param string $svalue 关联数据.
- * @param array $dbData 此数组数据结构一定要是["after_items" => [0, 1, 2], "before_items" => [0, 1, 2]], after_items,before_items 是一个二维码数组.
- * @return bool
- */
- protected function log(string $subject, $svalue = '', $dbData = [])
- {
- list($module, $action) = $this->getModuleAndAction();
- $inputs = [
- 'agent_uid' => '',
- 'username' => '',
- 'nick' => '匿名',
- 'subject' => mb_strcut((string)$subject, 0, 700),
- 'module' => $module,
- 'action' => $action,
- 'svalue' => !empty($svalue) ? mb_strcut((string)$svalue, 0, 700) : '',
- 'db_data' => $dbData,
- ];
- $this->getLogRepo()->createOne($inputs);
- return true;
- }
- /**
- * 获取日志仓库.
- * @return AgentLogRepository|null
- */
- protected function getLogRepo()
- {
- if (empty($this->logRepo)) {
- $this->logRepo = make(AgentLogRepository::class);
- }
- return $this->logRepo;
- }
- }
|