Skip to content

Instantly share code, notes, and snippets.

@mikield
Created September 2, 2022 14:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikield/47e38b03b0b4bafc04a19d5efc59d2b6 to your computer and use it in GitHub Desktop.
Save mikield/47e38b03b0b4bafc04a19d5efc59d2b6 to your computer and use it in GitHub Desktop.
A Laravel Auth Provider to create a Web3 Public key auth system.
<?php
namespace App\Providers\Web3PubKey;
use App\Models\User;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use SodiumException;
use Tighten\SolanaPhpSdk\Exceptions\InputValidationException;
use Tighten\SolanaPhpSdk\Util\Buffer;
use function Sodium\crypto_sign_verify_detached;
class Web3PubKeyAuthProvider implements UserProvider
{
public function __construct(private readonly User $model)
{
}
public static function getSignatureMessage(string $publicKey): string
{
return trans('Signing this message, I confirm that I am owner of :key', ['key' => $publicKey]);
}
public function retrieveById($identifier): Authenticatable|null
{
/** @phpstan-ignore-next-line */
return $this->model->find($identifier);
}
public function retrieveByToken($identifier, $token)
{
//no remember token
}
public function updateRememberToken(Authenticatable $user, $token): void
{
//no remember token
}
public function retrieveByCredentials(array $credentials): Authenticatable|null
{
return $this->model->where('auth_token', $credentials['public_key'])->first();
}
/**
* @throws InputValidationException
* @throws SodiumException
*/
public function validateCredentials(Authenticatable $user, array $credentials): bool
{
if (!array_key_exists('public_key', $credentials) ||
!array_key_exists('signature', $credentials)
) {
return false;
}
return $this->validateSignature($credentials['public_key'], $credentials['signature']);
}
/**
* @throws InputValidationException
* @throws SodiumException
*/
private function validateSignature(string $publicKey, array $signature): bool
{
$signatureBuffer = new Buffer($signature);
$message = self::getSignatureMessage($publicKey);
$publicKeyBuffer = Buffer::fromBase58($publicKey);
return crypto_sign_verify_detached($signatureBuffer->toString(), $message, $publicKeyBuffer->toString());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment