PHP code example of jbtronics / 2fa-webauthn

1. Go to this page and download the library: Download jbtronics/2fa-webauthn library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

jbtronics / 2fa-webauthn example snippets


use Jbtronics\TFAWebauthn\Model\TwoFactorInterface as WebauthnTwoFactorInterface;

class User implements WebauthnTwoFactorInterface
{
    /** 
     * @var Collection<int, PublicKeyCredentialSource>
     * @ORM\OneToMany(targetEntity="App\Entity\WebauthnKey", mappedBy="user", cascade={"REMOVE"}, orphanRemoval=true)
     */
    private $webauthnKeys;
    
    /**
     * Determines whether the user has 2FA using Webauthn enabled
     * @return bool True if the webauthn 2FA is enabled, false otherwise
     */
    public function isWebAuthnAuthenticatorEnabled(): bool
    {
        //Return true to enable webauthn 2FA
        return count($this->webauthnKeys) > 0;
    }
    
    /**
     * Returns a list of all legacy U2F keys, associated with this user
     * Return an empty array, if this user does not have any legacy U2F keys.
     * @return iterable<LegacyU2FKeyInterface>
     */
    public function getLegacyU2FKeys(): iterable
    {
        return []; //If you have no legacy U2F keys, return just an empty array
        //return $this->u2f_keys; //Otherwise return the legacy keys (see migration section below)
    }

    /**
     * Returns a list of all webauthn keys, associated with this user
     * @return iterable<PublicKeyCredentialSource>
     */
    public function getWebauthnKeys(): iterable
    {
        return $this->webauthnKeys;
    }

    /**
     * Returns the webauthn user entity that should be used for this user.
     * @return PublicKeyCredentialUserEntity
     */
    public function getWebAuthnUser(): PublicKeyCredentialUserEntity
    {
        //Return webauthn user definition for this user. As we just use it as an two-factor authentication, the values here are most likely not that important
        return new PublicKeyCredentialUserEntity(
            $this->getUsername(), // The Webauthn Name (like a username)
            $this->getID(), // A unique identifier for this user
            $this->getDisplayName() // The display name of this user (optional, otherwise null)
        );
    }
}


declare(strict_types=1);

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\UuidInterface;
use Webauthn\PublicKeyCredentialSource as BasePublicKeyCredentialSource;
use Webauthn\TrustPath\TrustPath;

/**
 * @ORM\Table(name="webauthn_keys")
 * @ORM\Entity()
 */
class WebAuthnKey extends BasePublicKeyCredentialSource
{
    /**
     * @var string
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    
    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="webauthnKeys")
     **/
    protected ?User $user = null;
    
    //You can declare additional fields too, if you want to store additional information about the key (like a name)
    private $name;


    public function getId(): string
    {
        return $this->id;
    }
    
    public static function fromRegistration(BasePublicKeyCredentialSource $registration): self
    {
        return new static(
            $registration->getPublicKeyCredentialId(),
            $registration->getType(),
            $registration->getTransports(),
            $registration->getAttestationType(),
            $registration->getTrustPath(),
            $registration->getAaguid(),
            $registration->getCredentialPublicKey(),
            $registration->getUserHandle(),
            $registration->getCounter(),
            $registration->getOtherUI()
        );
    }
}


    use Jbtronics\TFAWebauthn\Services\TFAWebauthnRegistrationHelper;Ä
    
    class WebauthnKeyRegistrationController extends AbstractController
{
    /**
     * @Route("/webauthn/register", name="webauthn_register")
     */
    public function register(Request $request, TFAWebauthnRegistrationHelper $registrationHelper, EntityManagerInterface $em)
    {

        //If form was submitted, check the auth response
        if ($request->getMethod() === 'POST') {
            $webauthnResponse = $request->request->get('_auth_code');

            //Retrieve other data from the form, that you want to store with the key
            $keyName = $request->request->get('keyName');


            try {
                //Check the response
                $new_key = $registrationHelper->checkRegistrationResponse($webauthnResponse);
            } catch (Exception $exception) {
                // Handle errors...
            }
            
            //If we got here, the registration was successful. Now we can store the new key in the database
            
            //Convert our returned key into an database entity and persist it...
            $keyEntity = WebauthnKey::fromRegistration($new_key);
            $keyEntity->setName($keyName);
            $keyEntity->setUser($this->getUser());

            $em->persist($keyEntity);
            $em->flush();
            
            
            $this->addFlash('success', 'Key registered successfully');
            //We are finished here so return to another page
            return $this->redirectToRoute('homepage');
        }


        return $this->render(
            'webauthn_register.html.twig',
            [
                //Generate the registration request
                'registrationRequest' => $registrationHelper->generateRegistrationRequestAsJSON(),
            ]
        );
    }
}