230 lines
6.3 KiB
PHP
230 lines
6.3 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
namespace App\Controller;
|
||
|
|
|
||
|
|
use App\Model\User;
|
||
|
|
use Hyperf\HttpServer\Contract\RequestInterface;
|
||
|
|
use Hyperf\HttpServer\Contract\ResponseInterface;
|
||
|
|
use Qbhy\HyperfAuth\AuthManager;
|
||
|
|
use Carbon\Carbon;
|
||
|
|
|
||
|
|
class AuthController extends AbstractController
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 用户注册
|
||
|
|
*/
|
||
|
|
public function register(RequestInterface $request, ResponseInterface $response)
|
||
|
|
{
|
||
|
|
$username = $request->input('username');
|
||
|
|
$password = $request->input('password');
|
||
|
|
$email = $request->input('email');
|
||
|
|
|
||
|
|
// 验证用户是否已存在
|
||
|
|
if (User::query()->where('username', $username)->exists()) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 400,
|
||
|
|
'message' => '用户名已存在',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
if (User::query()->where('email', $email)->exists()) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 400,
|
||
|
|
'message' => '邮箱已被注册',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 创建用户
|
||
|
|
$user = User::create([
|
||
|
|
'username' => $username,
|
||
|
|
'password' => $password, // 自动加密
|
||
|
|
'email' => $email,
|
||
|
|
'status' => 1,
|
||
|
|
]);
|
||
|
|
|
||
|
|
return $response->json([
|
||
|
|
'code' => 0,
|
||
|
|
'message' => '注册成功',
|
||
|
|
'data' => [
|
||
|
|
'id' => $user->id,
|
||
|
|
'username' => $user->username,
|
||
|
|
'email' => $user->email,
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 用户登录
|
||
|
|
*/
|
||
|
|
public function login(RequestInterface $request, ResponseInterface $response, AuthManager $auth)
|
||
|
|
{
|
||
|
|
$username = $request->input('username');
|
||
|
|
$password = $request->input('password');
|
||
|
|
|
||
|
|
// 查找用户
|
||
|
|
$user = User::query()->where('username', $username)->first();
|
||
|
|
|
||
|
|
if (!$user) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 401,
|
||
|
|
'message' => '用户名或密码错误',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 验证密码
|
||
|
|
if (!$user->verifyPassword($password)) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 401,
|
||
|
|
'message' => '用户名或密码错误',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查用户状态
|
||
|
|
if ($user->status !== 1) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 403,
|
||
|
|
'message' => '账号已被禁用',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 生成 Access Token
|
||
|
|
$token = $auth->guard('jwt')->login($user);
|
||
|
|
|
||
|
|
// 生成 Refresh Token
|
||
|
|
$refreshToken = bin2hex(random_bytes(32));
|
||
|
|
$user->refresh_token = $refreshToken;
|
||
|
|
$user->refresh_token_expires_at = Carbon::now()->addDays(30);
|
||
|
|
$user->save();
|
||
|
|
|
||
|
|
return $response->json([
|
||
|
|
'code' => 0,
|
||
|
|
'message' => '登录成功',
|
||
|
|
'data' => [
|
||
|
|
'access_token' => $token,
|
||
|
|
'refresh_token' => $refreshToken,
|
||
|
|
'token_type' => 'Bearer',
|
||
|
|
'expires_in' => 7200, // 2 小时
|
||
|
|
'user' => [
|
||
|
|
'id' => $user->id,
|
||
|
|
'username' => $user->username,
|
||
|
|
'email' => $user->email,
|
||
|
|
],
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 刷新 Access Token
|
||
|
|
*/
|
||
|
|
public function refresh(RequestInterface $request, ResponseInterface $response, AuthManager $auth)
|
||
|
|
{
|
||
|
|
$refreshToken = $request->input('refresh_token');
|
||
|
|
|
||
|
|
if (!$refreshToken) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 400,
|
||
|
|
'message' => '缺少 refresh_token 参数',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 查找用户
|
||
|
|
$user = User::query()->where('refresh_token', $refreshToken)->first();
|
||
|
|
|
||
|
|
if (!$user) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 401,
|
||
|
|
'message' => '无效的 refresh_token',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 验证 refresh token 是否过期
|
||
|
|
if (!$user->isRefreshTokenValid()) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 401,
|
||
|
|
'message' => 'refresh_token 已过期,请重新登录',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 检查用户状态
|
||
|
|
if ($user->status !== 1) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 403,
|
||
|
|
'message' => '账号已被禁用',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
// 生成新的 Access Token
|
||
|
|
$token = $auth->guard('jwt')->login($user);
|
||
|
|
|
||
|
|
// 可选:生成新的 Refresh Token(更安全)
|
||
|
|
$newRefreshToken = bin2hex(random_bytes(32));
|
||
|
|
$user->refresh_token = $newRefreshToken;
|
||
|
|
$user->refresh_token_expires_at = Carbon::now()->addDays(30);
|
||
|
|
$user->save();
|
||
|
|
|
||
|
|
return $response->json([
|
||
|
|
'code' => 0,
|
||
|
|
'message' => 'Token 刷新成功',
|
||
|
|
'data' => [
|
||
|
|
'access_token' => $token,
|
||
|
|
'refresh_token' => $newRefreshToken,
|
||
|
|
'token_type' => 'Bearer',
|
||
|
|
'expires_in' => 7200,
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 获取当前用户信息
|
||
|
|
*/
|
||
|
|
public function me(AuthManager $auth, ResponseInterface $response)
|
||
|
|
{
|
||
|
|
$user = $auth->guard('jwt')->user();
|
||
|
|
|
||
|
|
if (!$user) {
|
||
|
|
return $response->json([
|
||
|
|
'code' => 401,
|
||
|
|
'message' => '未授权',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $response->json([
|
||
|
|
'code' => 0,
|
||
|
|
'message' => '获取成功',
|
||
|
|
'data' => [
|
||
|
|
'id' => $user->id,
|
||
|
|
'username' => $user->username,
|
||
|
|
'email' => $user->email,
|
||
|
|
'status' => $user->status,
|
||
|
|
'ext' => $user->ext,
|
||
|
|
'created_at' => $user->created_at->toDateTimeString(),
|
||
|
|
],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 退出登录
|
||
|
|
*/
|
||
|
|
public function logout(AuthManager $auth, ResponseInterface $response)
|
||
|
|
{
|
||
|
|
$user = $auth->guard('jwt')->user();
|
||
|
|
|
||
|
|
if ($user instanceof User) {
|
||
|
|
// 清除 refresh token
|
||
|
|
$user->refresh_token = null;
|
||
|
|
$user->refresh_token_expires_at = null;
|
||
|
|
$user->save();
|
||
|
|
}
|
||
|
|
|
||
|
|
// 注销当前 token
|
||
|
|
$auth->guard('jwt')->logout();
|
||
|
|
|
||
|
|
return $response->json([
|
||
|
|
'code' => 0,
|
||
|
|
'message' => '退出成功',
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|