From ec6b900318879dcf7d54f799c2d26d0425f96367 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 17 Dec 2023 21:29:59 +0800 Subject: [PATCH] login --- app/Const/Filter.php | 14 ++ app/Const/RedisConst.php | 17 ++ app/Const/Responses.php | 9 ++ app/Http/Controllers/Base/BaseController.php | 39 +++++ .../Base/CustomerBaseController.php | 7 + app/Http/Controllers/Controller.php | 12 -- .../Customer/CustomerUserController.php | 108 +++++++++++++ app/Http/Kernel.php | 25 +-- app/Http/Middleware/AuthMiddleware.php | 44 +++++ app/Http/Middleware/ReqRecordMiddleware.php | 46 ++++++ app/Models/Base/BaseModel.php | 57 +++++++ app/Models/Base/CustomerBaseModel.php | 7 + app/Models/Customer/CustomerUser.php | 68 ++++++++ app/Service/AuthService.php | 152 ++++++++++++++++++ app/Tools/Tools.php | 43 +++++ public/index.html | 11 ++ public/nginx.htaccess | 1 + routes/api.php | 11 +- routes/channels.php | 6 +- routes/web.php | 6 +- 20 files changed, 652 insertions(+), 31 deletions(-) create mode 100644 app/Const/Filter.php create mode 100644 app/Const/RedisConst.php create mode 100644 app/Const/Responses.php create mode 100644 app/Http/Controllers/Base/BaseController.php create mode 100644 app/Http/Controllers/Base/CustomerBaseController.php delete mode 100644 app/Http/Controllers/Controller.php create mode 100644 app/Http/Controllers/Customer/CustomerUserController.php create mode 100644 app/Http/Middleware/AuthMiddleware.php create mode 100644 app/Http/Middleware/ReqRecordMiddleware.php create mode 100644 app/Models/Base/BaseModel.php create mode 100644 app/Models/Base/CustomerBaseModel.php create mode 100644 app/Models/Customer/CustomerUser.php create mode 100644 app/Service/AuthService.php create mode 100644 app/Tools/Tools.php create mode 100644 public/index.html create mode 100644 public/nginx.htaccess diff --git a/app/Const/Filter.php b/app/Const/Filter.php new file mode 100644 index 0000000..b2341be --- /dev/null +++ b/app/Const/Filter.php @@ -0,0 +1,14 @@ +validateMethodParams[$method])) { + request()->validate($this->validateMethodParams[$method]); + } + parent::__call($method, $parameters); + } + + function reply($code, $msg, $data = []): \Illuminate\Http\JsonResponse + { + return response()->json([ + 'code' => $code, + 'msg' => $msg, + 'data' => $data, + ]); + } + + function success($data = []): \Illuminate\Http\JsonResponse + { + return $this->reply(Responses::CODE_SUCCESS, 'success', $data); + } + + function error($msg = 'error', $data = []): \Illuminate\Http\JsonResponse + { + return $this->reply(Responses::CODE_ERROR, $msg, $data); + } + +} diff --git a/app/Http/Controllers/Base/CustomerBaseController.php b/app/Http/Controllers/Base/CustomerBaseController.php new file mode 100644 index 0000000..c60d23e --- /dev/null +++ b/app/Http/Controllers/Base/CustomerBaseController.php @@ -0,0 +1,7 @@ + [ + 'username' => 'required|alpha_dash:ascii|max:50', + 'password' => 'required|alpha_dash:ascii|max:50', + 'device' => 'required|alpha_dash:ascii|max:10', + ], + ]; + + function signIn(): \Illuminate\Http\JsonResponse + { + $request = request(); + $username = $request->input('username'); + $password = $request->input('password'); + $device = $request->input('device'); + + $oCustomerUser = new CustomerUser(); + $oUser = $oCustomerUser->findItemByUsername($username); + + if (!$oUser) { + return $this->error('用户名不存在'); + } + + if (!$oCustomerUser->checkPasswd($oUser->id,$password)) { + return $this->error('密码错误'); + } + + $oAuthService = new AuthService(); + $token = $oAuthService->createTokenToUser($oUser->id,$device); + + $data = [ + 'token' => $token, + 'user' => [ + 'id' => $oUser->id, + 'username' => $oUser->username, + 'nickname' => $oUser->nickname, + 'is_google_auth' => $oUser->is_google_auth, + 'created_at' => $oUser->created_at, + 'updated_at' => $oUser->updated_at, + ], + ]; + + return $this->success($data); + + } + + function signOut(): \Illuminate\Http\JsonResponse + { + $oAuthService = new AuthService(); + $token = $oAuthService->getTokenFromReq(); + $aUser = $oAuthService->getCurrentUser(); + $oAuthService->delTokenToUser($aUser['uid'],$token); + return $this->success(); + } + + function register() + { + $request = request(); + $username = $request->input('username'); + $password = $request->input('password'); + $device = $request->input('device'); + + $oCustomerUser = new CustomerUser(); + $oUser = $oCustomerUser->findItemByUsername($username,['id']); + + if ($oUser) { + return $this->error('用户名已存在'); + } + + $oUser = $oCustomerUser->addUser([ + 'username' => $username, + 'password' => $password, + 'nickname' => $username, + ]); + + if (!$oUser) { + return $this->error('注册失败'); + } + + $oAuthService = new AuthService(); + $token = $oAuthService->createTokenToUser($oUser->id,$device); + + $data = [ + 'token' => $token, + 'user' => [ + 'id' => $oUser->id, + 'username' => $oUser->username, + 'nickname' => $oUser->nickname, + 'is_google_auth' => $oUser->is_google_auth, + 'created_at' => $oUser->created_at, + 'updated_at' => $oUser->updated_at, + ], + ]; + + return $this->success($data); + } + +} diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 494c050..27c4076 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -42,6 +42,7 @@ class Kernel extends HttpKernel // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, \Illuminate\Routing\Middleware\ThrottleRequests::class.':api', \Illuminate\Routing\Middleware\SubstituteBindings::class, + \App\Http\Middleware\ReqRecordMiddleware::class, ], ]; @@ -53,16 +54,18 @@ class Kernel extends HttpKernel * @var array */ protected $middlewareAliases = [ - 'auth' => \App\Http\Middleware\Authenticate::class, - 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, - 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, - 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, - 'can' => \Illuminate\Auth\Middleware\Authorize::class, - 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, - 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, - 'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, - 'signed' => \App\Http\Middleware\ValidateSignature::class, - 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, - 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, +// 'auth' => \App\Http\Middleware\Authenticate::class, +// 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, +// 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, +// 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, +// 'can' => \Illuminate\Auth\Middleware\Authorize::class, +// 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, +// 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, +// 'precognitive' => \Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests::class, +// 'signed' => \App\Http\Middleware\ValidateSignature::class, +// 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, +// 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + 'auth' => \App\Http\Middleware\AuthMiddleware::class, + ]; } diff --git a/app/Http/Middleware/AuthMiddleware.php b/app/Http/Middleware/AuthMiddleware.php new file mode 100644 index 0000000..28fd66b --- /dev/null +++ b/app/Http/Middleware/AuthMiddleware.php @@ -0,0 +1,44 @@ +getTokenFromReq($request); + $aUserInfo = $oAuthService->getUserInfoByToken($sToken); + if($aUserInfo == null){ + return response()->json([ + 'code'=>Responses::CODE_ERROR, + 'msg'=>'未登录', + ]); + } + $oCustomerUser = new \App\Models\Customer\CustomerUser(); + $oCustomerUser = $oCustomerUser->findUserByUidWithCache($aUserInfo['uid']); + if(empty($oCustomerUser)){ + return response()->json([ + 'code'=>Responses::CODE_ERROR, + 'msg'=>'用户不存在', + ]); + } + $oAuthService->setCurrentUser($oCustomerUser->toArray()); + + + return $next($request); + } +} diff --git a/app/Http/Middleware/ReqRecordMiddleware.php b/app/Http/Middleware/ReqRecordMiddleware.php new file mode 100644 index 0000000..5bf88a3 --- /dev/null +++ b/app/Http/Middleware/ReqRecordMiddleware.php @@ -0,0 +1,46 @@ +getClientIp(); + $sReqUrl = $request->getUri(); + $sReqMethod = $request->getMethod(); + $sReqParams = json_encode($request->all()); + $sReqTime = date('Y-m-d H:i:s'); + $sReqUserAgent = $request->userAgent(); + $sReqReferer = $request->headers->get('referer'); + $sReqHeader = json_encode($request->headers->all()); + + $aData = [ + 'req_id'=>$sReqId, + 'req_ip'=>$sReqIp, + 'req_url'=>$sReqUrl, + 'req_method'=>$sReqMethod, + 'req_params'=>Tools::filterDataParams($sReqParams,Filter::REQ_LOG_FILTER), + 'req_time'=>$sReqTime, + 'req_user_agent'=>$sReqUserAgent, + 'req_referer'=>$sReqReferer, + 'req_header'=>$sReqHeader, + ]; + Log::info('req_record',$aData); + return $next($request); + } +} diff --git a/app/Models/Base/BaseModel.php b/app/Models/Base/BaseModel.php new file mode 100644 index 0000000..ad9b398 --- /dev/null +++ b/app/Models/Base/BaseModel.php @@ -0,0 +1,57 @@ + $value) { + if (!in_array($key, $this->fillable)) { + unset($aItem[$key]); + } + } + return $aItem; + } + + function addItem($aItem): Model|\Illuminate\Database\Eloquent\Builder|bool + { + $aItem = $this->checkColInFill($aItem); + if (empty($aItem)) return false; + return $this->newQuery()->create($aItem); + } + + function delItem($id) + { + return $this->newQuery()->where($this->primaryKey, $id)->delete(); + } + + function updateItem($aItem): bool|int + { + $aItem = $this->checkColInFill($aItem); + if (empty($aItem)) return false; + if (isset($aItem[$this->primaryKey])) return false; + return $this->newQuery()->where($this->primaryKey,$aItem[$this->primaryKey])->update($aItem); + } + + function findItem($id,$col=['*']): Model|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->newQuery()->find($id,$col); + } + + function findItemByWhere($aWhere,$col=['*']): Model|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->newQuery()->where($aWhere)->first($col); + } + + function getItemsByWhere($aWhere,$col=['*']): \Illuminate\Database\Eloquent\Collection|array + { + return $this->newQuery()->where($aWhere)->get($col); + } + + + +} diff --git a/app/Models/Base/CustomerBaseModel.php b/app/Models/Base/CustomerBaseModel.php new file mode 100644 index 0000000..c4ae3fe --- /dev/null +++ b/app/Models/Base/CustomerBaseModel.php @@ -0,0 +1,7 @@ + Hash::make($value), + ); + } + + function checkPasswd($iUid,$sPasswd):bool + { + $oUser = $this->where('id',$iUid)->first(); + if(empty($oUser)) return false; + return Hash::check($sPasswd,$oUser->password); + } + + function addUser($aItem): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|bool + { +// if(isset($aItem['password']) && !empty($aItem['password'])) $aItem['password'] = Hash::make($aItem['password']); + return $this->addItem($aItem); + } + + function findItemByUsername($sUsername,$col=['*']): \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null + { + return $this->newQuery()->where('username',$sUsername)->first($col); + } + + function findUserByUidWithCache($iUid): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder|array|null + { + return Cache::remember(RedisConst::ORM_CACHE_USER.$iUid,RedisConst::ORM_FIND_CACHE_SECOND,function ()use ($iUid){ + return $this->findItem($iUid); + }); + } + + + +} diff --git a/app/Service/AuthService.php b/app/Service/AuthService.php new file mode 100644 index 0000000..0b3dc3b --- /dev/null +++ b/app/Service/AuthService.php @@ -0,0 +1,152 @@ + '', + 'device' => '', + ]; + const uidTokenList = [ + 'token_1' => [ + 'device' => '', + 'created_time' => '', + 'exp_time' => '', + ], + ]; + + function checkTokenLogin($sToken): bool + { + return $this->getUserInfoByToken($sToken) != null; + } + + function getUserInfoByToken($sToken) + { + if (empty($sToken)) return null; + $sUidInfo = Redis::get(RedisConst::TOKEN_UID . $sToken); + if (empty($sUidInfo)) return null; + return unserialize($sUidInfo); + } + + function setUserInfoToToken($sToken, $iUid, $sDevice) + { + $sUidInfo = serialize([ + 'uid' => $iUid, + 'device' => $sDevice, + ]); + return Redis::set(RedisConst::TOKEN_UID . $sToken, $sUidInfo, RedisConst::COMMON_EXP_TIME); + } + + function delUserInfoToToken($sToken) + { + return Redis::del(RedisConst::TOKEN_UID . $sToken); + } + + function getAllTokenInfoByUid($iUid) + { + $sTokenList = Redis::get(RedisConst::UID_TOKENS . $iUid); + if (empty($sToken)) return null; + return unserialize($sTokenList); + } + + function checkTokenInUid($iUid, $sToken): bool + { + $aTokenInfoList = $this->getAllTokenInfoByUid($iUid); + if (empty($aTokenInfoList)) return false; + $aTokenList = array_keys($aTokenInfoList); + return in_array($sToken, $aTokenList); + } + + function addTokenToUidInfo($iUid, $sToken, $sDevice) + { + $aTokenInfoList = $this->getAllTokenInfoByUid($iUid); + if (empty($aTokenInfoList)) { + $aTokenInfoList = []; + } + $aTokenInfoList[$sToken] = [ + 'device' => $sDevice, + 'created_time' => Carbon::now()->toDateTimeString(), + 'exp_time' => Carbon::parse(time() + RedisConst::COMMON_EXP_TIME)->toDateTimeString(), + ]; + $sTokenList = serialize($aTokenInfoList); + return Redis::set(RedisConst::UID_TOKENS . $iUid, $sTokenList); + } + + function delTokenByUidInfo($iUid, $sToken) + { + $aTokenInfoList = $this->getAllTokenInfoByUid($iUid); + if (empty($aTokenInfoList)) return false; + if (!isset($aTokenInfoList[$sToken])) return false; + unset($aTokenInfoList[$sToken]); + $sTokenList = serialize($aTokenInfoList); + return Redis::set(RedisConst::UID_TOKENS . $iUid, $sTokenList); + } + + function getTokenFromReq(\Illuminate\Http\Request $request = null) + { + if ($request == null) $request = request(); + $sToken = $request->header('_token'); + if (!empty($sToken)) return $sToken; + $sToken = $request->input('_token'); + if (!empty($sToken)) return $sToken; + return null; + } + + function generateTokenStr(): string + { + return time() . Tools::generateRandStr(24); + } + + //登入使用 + function createTokenToUser($iUid, $sDevice): string + { + do { + $sToken = $this->generateTokenStr(); + if (!$this->checkTokenLogin($sToken)) break; + } while (1); + + $this->setUserInfoToToken($sToken, $iUid, $sDevice); + $this->addTokenToUidInfo($iUid, $sToken, $sDevice); + return $sToken; + } + + //登出使用 + function delTokenToUser($iUid, $sToken): void + { + $this->delUserInfoToToken($sToken); + $this->delTokenByUidInfo($iUid, $sToken); + } + + function getTokenInfo() + { + $sToken = $this->getTokenFromReq(); + if (empty($sToken)) return null; + $aUserInfo = $this->getUserInfoByToken($sToken); + if (empty($aUserInfo)) return null; + return $aUserInfo; + } + + function setCurrentUser(array $aUser): void + { + app()->singleton('customerUser',function () use ($aUser){ + return $aUser; + }); + } + + function getCurrentUser() + { + if(app()->has('customerUser')){ + return app()->get('customerUser'); + } + return null; + } + + +} diff --git a/app/Tools/Tools.php b/app/Tools/Tools.php new file mode 100644 index 0000000..5e8bfa0 --- /dev/null +++ b/app/Tools/Tools.php @@ -0,0 +1,43 @@ + 0 ? $iEnd : $iStrLen - $iStart; + $sHideStr = ''; + for ($i = 0; $i < $iEnd; $i++) { + $sHideStr .= $sReplace; + } + return mb_substr($sStr, 0, $iStart) . $sHideStr . mb_substr($sStr, $iStart + $iEnd); + } + + +} diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..9e829f5 --- /dev/null +++ b/public/index.html @@ -0,0 +1,11 @@ + + + + + Title + + + +asd + + diff --git a/public/nginx.htaccess b/public/nginx.htaccess new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/public/nginx.htaccess @@ -0,0 +1 @@ + diff --git a/routes/api.php b/routes/api.php index 889937e..8334345 100644 --- a/routes/api.php +++ b/routes/api.php @@ -14,6 +14,13 @@ use Illuminate\Support\Facades\Route; | */ -Route::middleware('auth:sanctum')->get('/user', function (Request $request) { - return $request->user(); +//Route::middleware('auth:sanctum')->get('/user', function (Request $request) { +// return $request->user(); +//}); + +//需要登录的路由 +Route::middleware('auth')->group(function () { + Route::post('/test', function () { + return 'test'; + }); }); diff --git a/routes/channels.php b/routes/channels.php index 5d451e1..f46585c 100644 --- a/routes/channels.php +++ b/routes/channels.php @@ -13,6 +13,6 @@ use Illuminate\Support\Facades\Broadcast; | */ -Broadcast::channel('App.Models.User.{id}', function ($user, $id) { - return (int) $user->id === (int) $id; -}); +//Broadcast::channel('App.Models.User.{id}', function ($user, $id) { +// return (int) $user->id === (int) $id; +//}); diff --git a/routes/web.php b/routes/web.php index d259f33..f4e8c0b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -13,6 +13,6 @@ use Illuminate\Support\Facades\Route; | */ -Route::get('/', function () { - return view('welcome'); -}); +//Route::get('/', function () { +// return view('welcome'); +//});