初始化
This commit is contained in:
@@ -0,0 +1,244 @@
|
||||
<?php
|
||||
/**
|
||||
* 认证服务
|
||||
* 杰柏特半导体后台管理系统
|
||||
*/
|
||||
|
||||
namespace app\service;
|
||||
|
||||
use app\model\Admin;
|
||||
|
||||
class AuthService
|
||||
{
|
||||
private $adminModel;
|
||||
private $config;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->adminModel = new Admin();
|
||||
$this->config = require __DIR__ . '/../config/app.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户登录
|
||||
*/
|
||||
public function login($username, $password)
|
||||
{
|
||||
if (empty($username) || empty($password)) {
|
||||
return ['code' => 400, 'msg' => '用户名和密码不能为空'];
|
||||
}
|
||||
|
||||
$admin = $this->adminModel->findByUsername($username);
|
||||
|
||||
if (!$admin) {
|
||||
return ['code' => 400, 'msg' => '用户名或密码错误'];
|
||||
}
|
||||
|
||||
if ($admin['status'] != 1) {
|
||||
return ['code' => 403, 'msg' => '账号已被禁用,请联系管理员'];
|
||||
}
|
||||
|
||||
if (!password_verify($password, $admin['password'])) {
|
||||
return ['code' => 400, 'msg' => '用户名或密码错误'];
|
||||
}
|
||||
|
||||
// 更新登录信息
|
||||
$ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';
|
||||
$this->adminModel->updateLoginInfo($admin['id'], $ip);
|
||||
|
||||
// 生成Token
|
||||
$token = $this->generateToken($admin);
|
||||
|
||||
return [
|
||||
'code' => 200,
|
||||
'msg' => '登录成功',
|
||||
'data' => [
|
||||
'token' => $token,
|
||||
'userinfo' => [
|
||||
'id' => $admin['id'],
|
||||
'username' => $admin['username'],
|
||||
'nickname' => $admin['nickname'] ?: $admin['username'],
|
||||
'avatar' => $admin['avatar'] ?: '',
|
||||
'category' => $admin['category'] ?? 'mes',
|
||||
'role' => ($admin['category'] === 'all') ? 'super_admin' : 'admin',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成JWT Token
|
||||
*/
|
||||
private function generateToken($admin)
|
||||
{
|
||||
$header = base64_encode(json_encode([
|
||||
'alg' => 'HS256',
|
||||
'typ' => 'JWT',
|
||||
]));
|
||||
|
||||
$payload = base64_encode(json_encode([
|
||||
'id' => $admin['id'],
|
||||
'username' => $admin['username'],
|
||||
'iat' => time(),
|
||||
'exp' => time() + $this->config['token_expire'],
|
||||
]));
|
||||
|
||||
$signature = base64_encode(hash_hmac(
|
||||
'sha256',
|
||||
"{$header}.{$payload}",
|
||||
$this->config['token_secret'],
|
||||
true
|
||||
));
|
||||
|
||||
return "{$header}.{$payload}.{$signature}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证Token
|
||||
*/
|
||||
public function verifyToken($token)
|
||||
{
|
||||
if (empty($token)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts = explode('.', $token);
|
||||
if (count($parts) !== 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
[$header, $payload, $signature] = $parts;
|
||||
|
||||
// 验证签名
|
||||
$expectedSig = base64_encode(hash_hmac(
|
||||
'sha256',
|
||||
"{$header}.{$payload}",
|
||||
$this->config['token_secret'],
|
||||
true
|
||||
));
|
||||
|
||||
if (!hash_equals($expectedSig, $signature)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 解析payload
|
||||
$data = json_decode(base64_decode($payload), true);
|
||||
if (!$data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 检查过期
|
||||
if (isset($data['exp']) && $data['exp'] < time()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*/
|
||||
public function getCurrentUser()
|
||||
{
|
||||
$token = $this->getBearerToken();
|
||||
if (!$token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = $this->verifyToken($token);
|
||||
if (!$payload) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->adminModel->find($payload['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从请求头获取Token
|
||||
* 优先级: Authorization > X-Auth-Token (Nginx兼容)
|
||||
*/
|
||||
public function getBearerToken()
|
||||
{
|
||||
// 1. 标准 Authorization header
|
||||
$headers = $this->getAuthorizationHeader();
|
||||
if ($headers && preg_match('/Bearer\s+(.+)$/i', $headers, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
|
||||
// 2. 自定义 header X-Auth-Token (Nginx 默认不丢弃自定义 header)
|
||||
// 前端发送: X-Auth-Token: Bearer <token>
|
||||
$xAuthToken = $_SERVER['HTTP_X_AUTH_TOKEN'] ?? null;
|
||||
if ($xAuthToken) {
|
||||
if (preg_match('/^Bearer\s+(.+)$/i', $xAuthToken, $m)) {
|
||||
return $m[1];
|
||||
}
|
||||
// 也支持直接传 token 值
|
||||
return $xAuthToken;
|
||||
}
|
||||
|
||||
// 3. URL 参数 token(用于 window.open / <a href> 下载等场景)
|
||||
$urlToken = $_GET['token'] ?? null;
|
||||
if ($urlToken) {
|
||||
return $urlToken;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Authorization头
|
||||
* 兼容 Apache / Nginx / IIS / PHP-FPM 等多种环境
|
||||
*/
|
||||
private function getAuthorizationHeader()
|
||||
{
|
||||
// 1. Apache / Nginx (with pass) 标准
|
||||
if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
|
||||
return $_SERVER['HTTP_AUTHORIZATION'];
|
||||
}
|
||||
|
||||
// 2. Apache rewrite 后
|
||||
if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||
return $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
||||
}
|
||||
|
||||
// 3. Nginx + PHP-FPM: Authorization 可能被放在其他变量中
|
||||
if (isset($_SERVER['AUTHORIZATION'])) {
|
||||
return $_SERVER['AUTHORIZATION'];
|
||||
}
|
||||
|
||||
// 4. apache_request_headers (Apache/FastCGI)
|
||||
if (function_exists('apache_request_headers')) {
|
||||
$headers = apache_request_headers();
|
||||
if (isset($headers['Authorization'])) {
|
||||
return $headers['Authorization'];
|
||||
}
|
||||
// 有些环境下 header 名是小写的
|
||||
if (isset($headers['authorization'])) {
|
||||
return $headers['authorization'];
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Nginx + PHP-FPM 终极兜底: 从原始 HTTP 头中提取
|
||||
// 有些 Nginx 配置下,Authorization 可能根本不在 $_SERVER 中
|
||||
// 尝试从 getallheaders() 获取 (PHP-FPM built-in)
|
||||
if (function_exists('getallheaders')) {
|
||||
$allHeaders = getallheaders();
|
||||
if (isset($allHeaders['Authorization'])) {
|
||||
return $allHeaders['Authorization'];
|
||||
}
|
||||
if (isset($allHeaders['authorization'])) {
|
||||
return $allHeaders['authorization'];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成密码哈希
|
||||
*/
|
||||
public function hashPassword($password)
|
||||
{
|
||||
return password_hash($password, PASSWORD_BCRYPT);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user