diff --git a/app/Http/Controllers/UserWebAuthnController.php b/app/Http/Controllers/UserWebAuthnController.php index d891051..8122db3 100644 --- a/app/Http/Controllers/UserWebAuthnController.php +++ b/app/Http/Controllers/UserWebAuthnController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers; +use App\Models\User; use App\WebAuthn\Repository\PublicKeyCredentialSourceRepositoryImpl; use App\WebAuthn\WebAuthnService; use Cose\Algorithm\Manager; @@ -32,11 +33,6 @@ use Webauthn\TokenBinding\IgnoreTokenBindingHandler; class UserWebAuthnController extends BaseController { - public function webauthn_login(Request $request) - { - return view("user.webauthn.login"); - } - public function register_options(Request $request): PublicKeyCredentialCreationOptions { $userEntity = new PublicKeyCredentialUserEntity( @@ -49,17 +45,44 @@ class UserWebAuthnController extends BaseController return WebAuthnService::createRequestOptions($userEntity, $challenge); } - public function login_options(Request $request): PublicKeyCredentialRequestOptions + public function login_options(Request $request) { $challenge = random_bytes(32); $request->session()->put("webauthn_login_challenge", $challenge); + $username = $request->post("username", ""); + if ($username) { + $query = User::query(); + if (str_contains($username, "@")) { + $query->where("email", "=", $username); + } else { + $query->where("name", "=", $username); + } + $user = $query->first(); + if ($user) { + $userHandle = (string) $user->id; + } else { + return new Response([ + "success" => false, + "code" => 401, + "message" => "无此用户" + ], 401); + } + } else { + $userHandle = "0"; + } + $request->session()->put("webauthn_login_user", $userHandle); $publicKeyCredentialRequestOptions = new PublicKeyCredentialRequestOptions( $challenge ); $publicKeyCredentialRequestOptions->setUserVerification( PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_REQUIRED ); - $publicKeyCredentialRequestOptions->allowCredentials([]); + $publicKeyCredentialSources = WebAuthnService::getPublicKeyCredentialSourceRepository()->findAllForUserEntity( + new PublicKeyCredentialUserEntity("", $userHandle, "") + ); + array_map(function ($source) use ($publicKeyCredentialRequestOptions) { + $publicKeyCredentialRequestOptions->allowCredential($source->getPublicKeyCredentialDescriptor()); + } ,$publicKeyCredentialSources); return $publicKeyCredentialRequestOptions; } @@ -120,7 +143,24 @@ class UserWebAuthnController extends BaseController $publicKeyCredentialRequestOptions = new PublicKeyCredentialRequestOptions( $request->session()->remove("webauthn_login_challenge") ); + $publicKeyCredentialSources = WebAuthnService::getPublicKeyCredentialSourceRepository()->findAllForUserEntity( + new PublicKeyCredentialUserEntity("", "0", "") + ); $publicKeyCredential = WebAuthnService::getPublicKeyCredentialLoader()->loadArray($request->json()->all()); + $userHandle = null; + foreach ($publicKeyCredentialSources as $source) { + if ($source->getPublicKeyCredentialId() === $publicKeyCredential->getRawId()) { + $userHandle = $source->getUserHandle(); + break; + } + } + if ($userHandle === null) { + return new Response([ + "success" => false, + "code" => 401, + "message" => "无此密钥" + ], 401); + } $authenticatorAssertionResponse = $publicKeyCredential->getResponse(); if (!$authenticatorAssertionResponse instanceof AuthenticatorAssertionResponse) { //e.g. process here with a redirection to the public key login/MFA page. @@ -136,7 +176,7 @@ class UserWebAuthnController extends BaseController $authenticatorAssertionResponse, $publicKeyCredentialRequestOptions, ServerRequest::fromGlobals(), - $authenticatorAssertionResponse->getUserHandle(), + $userHandle, ["localhost"] ); } catch (\Throwable $e) { diff --git a/app/WebAuthn/Repository/PublicKeyCredentialSourceRepositoryImpl.php b/app/WebAuthn/Repository/PublicKeyCredentialSourceRepositoryImpl.php index 046012e..ac04598 100644 --- a/app/WebAuthn/Repository/PublicKeyCredentialSourceRepositoryImpl.php +++ b/app/WebAuthn/Repository/PublicKeyCredentialSourceRepositoryImpl.php @@ -3,6 +3,7 @@ namespace App\WebAuthn\Repository; use App\Models\WebauthnCredential; +use Illuminate\Database\Eloquent\Builder; use Webauthn\PublicKeyCredentialSource; use Webauthn\PublicKeyCredentialSourceRepository; use Webauthn\PublicKeyCredentialUserEntity; @@ -52,18 +53,18 @@ class PublicKeyCredentialSourceRepositoryImpl implements PublicKeyCredentialSour /** * @var WebauthnCredential */ - return WebauthnCredential::query()->where(function ($query) use ($publicKeyCredentialId) { + return WebauthnCredential::query()->where(function (Builder $query) use ($publicKeyCredentialId) { $query->where("credential_id", "=", base64_encode($publicKeyCredentialId)); })->first(); } private function findAllModelByTypeFree(): array { - return WebauthnCredential::query()->where("type_free", "=", "1")->get()->toArray(); + return WebauthnCredential::query()->where("type_free", "=", "1")->get()->all(); } private function findAllModelByUserId(string $userId): array { - return WebauthnCredential::query()->where("user_id", "=", $userId)->get()->toArray(); + return WebauthnCredential::query()->where("user_id", "=", $userId)->get()->all(); } } diff --git a/resources/js/webauthn.js b/resources/js/webauthn.js index a4a0be2..0571d65 100644 --- a/resources/js/webauthn.js +++ b/resources/js/webauthn.js @@ -13,13 +13,16 @@ const webauthn_login = useLogin({ window.webauthn_register = webauthn_register; window.webauthn_login = webauthn_login; (function() { - const loginForm = window.document.getElementById("webauthn_login_form"); - console.log(loginForm) - if (loginForm) { - loginForm.addEventListener("submit", function (e) { + const button = window.document.getElementById("do_webauthn_login"); + if (button) { + button.addEventListener("click", function (e) { + const loginForm = window.document.getElementById("webauthn_login_form"); + if (!loginForm) return; e.preventDefault(); const formData = new FormData(loginForm) - webauthn_login(formData) + webauthn_login({ + username: formData.get("username") + }) .then(() => { // 成功登录 window.location.href = "/" diff --git a/resources/views/user/login.blade.php b/resources/views/user/login.blade.php index ab7578a..439cc87 100644 --- a/resources/views/user/login.blade.php +++ b/resources/views/user/login.blade.php @@ -4,10 +4,11 @@ 登录 + @include("common.header") -
+
登录
@csrf