cms-manage/app/controller/backend/AccountController.php

192 lines
6.7 KiB
PHP

<?php
declare (strict_types = 1);
namespace app\controller\backend;
use app\model\AdminMenu;
use app\model\PhoneCode;
use app\service\PhoneCodeService;
use app\service\RoleService;
use app\service\sms\ALiSms;
use app\validate\LoginValidate;
use app\model\Admin;
use think\exception\ValidateException;
use think\facade\Cache;
use think\facade\Env;
use think\facade\Lang;
use xiaodi\JWTAuth\Facade\Jwt;
class AccountController extends \app\BaseController
{
/**
* @param Admin $adminModel
* @return \think\response\Json
* @throws \app\exception\ModelEmptyException
* @throws \app\exception\ModelException
*/
public function login(Admin $adminModel): \think\response\Json
{
if (request()->isPost()) {
$param = request()->only(['account','password']);
$pattern = "/^[\w\.-]+@\w+\.\w+(\.\w+)?$/";
if(!env('APP_DEBUG') == true || !(preg_match($pattern,$param['account']) && env('APP_DEBUG') == true)){
$param['account'] = $this->RSA_openssl($param['account'], 'decode');
$param['password'] = $this->RSA_openssl($param['password'], 'decode');
}
// 检验完整性
try {
validate(LoginValidate::class)->scene('login')->check($param);
} catch (ValidateException $e) {
return jsonReturn(-1, $e->getError());
}
$where = ['account' => $param['account']];
$admin = $adminModel->getAdmin($where,['role'])['data'];
if (!checkPassword($param['password'], $admin['password'])) {
return jsonReturn(-2, Lang::get('用户名密码不正确'));
}
if ($admin['status'] == 2) {
return jsonReturn(-3, Lang::get('该账号已经被禁用'));
}
if ($admin['code_auth'] == 1 && !empty($admin['phone'])) {
$data = [
'phone' => $admin['phone'],
'code' => random_code_type(6, 'number'),
'seller_id' => $admin['seller_id'],
'expired_time' => date('Y-m-d H:i:s', time() + 5 * 60), // 登录验证码5分钟有效
];
//保存发送code记录
$codeModel = new PhoneCode();
$codeModel->insertGetId([
'phone' => $data['phone'],
'code' => $data['code'],
'expired_time' => $data['expired_time']
]);
Cache::set($admin['phone'] . '_login', time(), 5 * 60);
if (Env::get('APP_DEBUG')) {
return jsonReturn(0, 'code_auth', $data);
}
$res = ALiSms::sendOneAuthMsg($data);
if ($res['code'] != 0) {
return json($res);
}
return jsonReturn(0, 'code_auth', ['phone' => $admin['phone']]);
}
return $this->getMenuAndToken($admin);
}
}
/**
* @throws \app\exception\ModelEmptyException
* @throws \app\exception\ModelException
*/
public function authCode(Admin $adminModel): \think\response\Json
{
$param = request()->only(['phone','code']);
$param['phone'] = $this->RSA_openssl($param['phone'], 'decode');
$param['code'] = $this->RSA_openssl($param['code'], 'decode');
$authCodeRes = PhoneCodeService::authCode($param);
if ($authCodeRes['code'] != 0) {
return json($authCodeRes);
}
$where = ['phone' => $param['phone']];
$admin = $adminModel->getAdmin($where,['role'])['data'];
return $this->getMenuAndToken($admin);
}
/**
* @throws \app\exception\TokenException
*/
protected function getMenuAndToken($admin): \think\response\Json
{
// 缓存权限数据
$roleRes = RoleService::getMenuAndUpdateAuth($admin['id']);
// $token = Jwt::token([
// 'uid' => $admin['id'],
// 'name' => $admin['name'],
// 'seller_id' => $admin['seller_id']
// ]);
$loginTime = time();
// 登录日志
$data = [
'seller_id' => $admin['seller_id'],
'admin_id' => $admin['id'],
'admin_name' => $admin['name'],
'title' => $admin['name'].Lang('登录后台系统'),
'ip' => request()->ip(),
'agent' => request()->header()['user-agent'],
'login_time' => $loginTime
];
event('AdminLoginLog',$data);
// 更新最后登录时间
$admin->last_login_time = $loginTime;
$admin->save();
$menu = $roleRes['data'];
return jsonReturn(0, Lang::get('登录成功'), [
'token' => createUserToken([
'uid' => $admin['id'],
'name' => $admin['name'],
'seller_id' => $admin['seller_id']
],'admin'),
'user' => $admin,
'menu' => $menu,
]);
}
/**
* @description RSA公钥加密 私钥解密
* @param string $data 待加解密数据
* @param string $operate 操作类型 encode:加密 decode:解密
* @return string 返回加密内容/解密内容
* @throws \Exception
*/
protected function RSA_openssl(string $data, string $operate = 'encode'): string
{
//RSA 公钥
$rsa_public = config('system.rsa_public_key');
//RSA 私钥
$rsa_private = config('system.rsa_private_key');
//RSA 公钥加密
if ('encode' == $operate) {
$public_key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($rsa_public, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
$key = openssl_pkey_get_public($public_key);
if (!$key) {
throw new \Exception('公钥不可用,请联系系统维护人员');
}
$return_en = openssl_public_encrypt($data, $crypted, $key);
if (!$return_en) {
throw new \Exception('公钥加密失败,请联系系统维护人员');
}
return base64_encode($crypted);
}
//RSA 私钥解密
if ('decode' == $operate) {
$private_key = "-----BEGIN PRIVATE KEY-----\n" . wordwrap($rsa_private, 64, "\n", true) . "\n-----END PRIVATE KEY-----";
$key = openssl_pkey_get_private($private_key);
if (!$key) {
throw new \Exception('私钥不可用,请联系系统维护人员');
}
$return_de = openssl_private_decrypt(base64_decode($data), $decrypted, $key);
if (!$return_de) {
throw new \Exception('私钥解密失败,请联系系统维护人员');
}
return $decrypted;
}
}
}