【私域操盘手】账号密码登录
This commit is contained in:
155
Server/application/common/service/AuthService.php
Normal file
155
Server/application/common/service/AuthService.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
namespace app\common\service;
|
||||
|
||||
use app\common\model\User;
|
||||
use app\common\util\JwtUtil;
|
||||
use think\facade\Log;
|
||||
|
||||
class AuthService
|
||||
{
|
||||
/**
|
||||
* 令牌有效期(秒)
|
||||
*/
|
||||
const TOKEN_EXPIRE = 7200;
|
||||
|
||||
/**
|
||||
* 短信服务实例
|
||||
* @var SmsService
|
||||
*/
|
||||
protected $smsService;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->smsService = new SmsService();
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
* @param string $username 用户名
|
||||
* @param string $password 密码
|
||||
* @param string $ip 登录IP
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function login($username, $password, $ip)
|
||||
{
|
||||
// 获取用户信息
|
||||
$user = User::getAdminUser($username, $password);
|
||||
|
||||
if (empty($user)) {
|
||||
// 记录登录失败
|
||||
Log::info('登录失败', ['username' => $username, 'ip' => $ip]);
|
||||
throw new \Exception('用户名或密码错误');
|
||||
}
|
||||
|
||||
// 生成JWT令牌
|
||||
$token = JwtUtil::createToken($user, self::TOKEN_EXPIRE);
|
||||
$expireTime = time() + self::TOKEN_EXPIRE;
|
||||
|
||||
// 记录登录成功
|
||||
Log::info('登录成功', ['username' => $username, 'ip' => $ip]);
|
||||
|
||||
return [
|
||||
'token' => $token,
|
||||
'token_expired' => $expireTime,
|
||||
'member' => $user
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机号验证码登录
|
||||
* @param string $mobile 手机号
|
||||
* @param string $code 验证码
|
||||
* @param string $ip 登录IP
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function mobileLogin($mobile, $code, $ip)
|
||||
{
|
||||
// 验证验证码
|
||||
if (!$this->smsService->verifyCode($mobile, $code, 'login')) {
|
||||
Log::info('验证码验证失败', ['mobile' => $mobile, 'ip' => $ip]);
|
||||
throw new \Exception('验证码错误或已过期');
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
$user = User::getUserByMobile($mobile);
|
||||
if (empty($user)) {
|
||||
Log::info('用户不存在', ['mobile' => $mobile, 'ip' => $ip]);
|
||||
throw new \Exception('用户不存在');
|
||||
}
|
||||
|
||||
// 生成JWT令牌
|
||||
$token = JwtUtil::createToken($user, self::TOKEN_EXPIRE);
|
||||
$expireTime = time() + self::TOKEN_EXPIRE;
|
||||
|
||||
// 记录登录成功
|
||||
Log::info('手机号登录成功', ['mobile' => $mobile, 'ip' => $ip]);
|
||||
|
||||
return [
|
||||
'token' => $token,
|
||||
'token_expired' => $expireTime,
|
||||
'member' => $user
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送登录验证码
|
||||
* @param string $mobile 手机号
|
||||
* @param string $type 验证码类型
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sendLoginCode($mobile, $type)
|
||||
{
|
||||
return $this->smsService->sendCode($mobile, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param array $userInfo JWT中的用户信息
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function getUserInfo($userInfo)
|
||||
{
|
||||
if (empty($userInfo)) {
|
||||
throw new \Exception('获取用户信息失败');
|
||||
}
|
||||
|
||||
// 移除不需要返回的字段
|
||||
unset($userInfo['exp']);
|
||||
unset($userInfo['iat']);
|
||||
|
||||
return $userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 刷新令牌
|
||||
* @param array $userInfo JWT中的用户信息
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function refreshToken($userInfo)
|
||||
{
|
||||
if (empty($userInfo)) {
|
||||
throw new \Exception('刷新令牌失败');
|
||||
}
|
||||
|
||||
// 移除过期时间信息
|
||||
unset($userInfo['exp']);
|
||||
unset($userInfo['iat']);
|
||||
|
||||
// 生成新令牌
|
||||
$token = JwtUtil::createToken($userInfo, self::TOKEN_EXPIRE);
|
||||
$expireTime = time() + self::TOKEN_EXPIRE;
|
||||
|
||||
return [
|
||||
'token' => $token,
|
||||
'token_expired' => $expireTime
|
||||
];
|
||||
}
|
||||
}
|
||||
124
Server/application/common/service/SmsService.php
Normal file
124
Server/application/common/service/SmsService.php
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace app\common\service;
|
||||
|
||||
use think\facade\Cache;
|
||||
use think\facade\Log;
|
||||
|
||||
class SmsService
|
||||
{
|
||||
/**
|
||||
* 验证码有效期(秒)
|
||||
*/
|
||||
const CODE_EXPIRE = 300;
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
* @param string $mobile 手机号
|
||||
* @param string $type 验证码类型
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function sendCode($mobile, $type)
|
||||
{
|
||||
// 检查发送频率
|
||||
$this->checkSendFrequency($mobile);
|
||||
|
||||
// 生成验证码
|
||||
$code = $this->generateCode();
|
||||
|
||||
try {
|
||||
// TODO: 对接实际的短信发送服务
|
||||
// 这里模拟发送成功
|
||||
$this->saveCode($mobile, $code, $type);
|
||||
|
||||
// 记录发送日志
|
||||
Log::info('验证码发送成功', [
|
||||
'mobile' => $mobile,
|
||||
'type' => $type,
|
||||
'code' => $code
|
||||
]);
|
||||
|
||||
return [
|
||||
'mobile' => $mobile,
|
||||
'expire' => self::CODE_EXPIRE
|
||||
];
|
||||
} catch (\Exception $e) {
|
||||
Log::error('验证码发送失败', [
|
||||
'mobile' => $mobile,
|
||||
'type' => $type,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
throw new \Exception('验证码发送失败,请稍后重试');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证验证码
|
||||
* @param string $mobile 手机号
|
||||
* @param string $code 验证码
|
||||
* @param string $type 验证码类型
|
||||
* @return bool
|
||||
*/
|
||||
public function verifyCode($mobile, $code, $type)
|
||||
{
|
||||
$key = $this->getCodeKey($mobile, $type);
|
||||
$savedCode = Cache::get($key);
|
||||
|
||||
if (!$savedCode || $savedCode !== $code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 验证成功后删除验证码
|
||||
Cache::rm($key);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查发送频率
|
||||
* @param string $mobile 手机号
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function checkSendFrequency($mobile)
|
||||
{
|
||||
$key = 'sms_frequency_' . $mobile;
|
||||
$lastSendTime = Cache::get($key);
|
||||
|
||||
if ($lastSendTime && time() - $lastSendTime < 60) {
|
||||
throw new \Exception('发送太频繁,请稍后再试');
|
||||
}
|
||||
|
||||
Cache::set($key, time(), 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码
|
||||
* @return string
|
||||
*/
|
||||
protected function generateCode()
|
||||
{
|
||||
return sprintf('%06d', random_int(0, 999999));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存验证码
|
||||
* @param string $mobile 手机号
|
||||
* @param string $code 验证码
|
||||
* @param string $type 验证码类型
|
||||
*/
|
||||
protected function saveCode($mobile, $code, $type)
|
||||
{
|
||||
$key = $this->getCodeKey($mobile, $type);
|
||||
Cache::set($key, $code, self::CODE_EXPIRE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存key
|
||||
* @param string $mobile 手机号
|
||||
* @param string $type 验证码类型
|
||||
* @return string
|
||||
*/
|
||||
protected function getCodeKey($mobile, $type)
|
||||
{
|
||||
return 'sms_code_' . $type . '_' . $mobile;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user