Code Monkey home page Code Monkey logo

laravel-fastlogin's Introduction

Allow your users to login with FaceID/TouchID

Latest Version on Packagist Total Downloads

Allow your users to register physical authentication devices (FaceID or TouchID on iPhones & macs, fingerprint on Android, Hello on Windows and USB keys) to skip entering their login credentials.

Installation

You can install the package via composer:

composer require m1guelpf/laravel-fastlogin

You'll then need to add the \M1guelpf\FastLogin\Models\Concerns\CanFastLogin trait to your user model and migrate your database by running php artisan migrate.

class User extends Authenticatable
{
    use CanFastLogin;
}

Usage

This package takes care of everything you need on the backend. To make our life easier on the frontend, we'll be using @web-auth/webauthn-helper and js-cookie. You can install them by running yarn add @web-auth/webauthn-helper js-cookie.

To get started, you need to have the user register a new credential. You can do so by presenting them with a modal when they login, or by adding the option to their settings page.

Note: Due to Apple's restrictions, you can only call the creation function after a user gesture, that is, the function needs to be invoked in an user-generated event (like a "click" event).

import Cookies from 'js-cookie'
import { useRegistration } from '@web-auth/webauthn-helper'

const onClick = () => {
    const token = Cookies.get('XSRF-TOKEN')

    useRegistration({
        actionUrl: route('fastlogin.create'),
        optionsUrl: route('fastlogin.create.details'),
        actionHeader: {
            'x-xsrf-token': token
        },
    }, {
        'x-xsrf-token': token
    })().then(() => {
        // credential has been added
    })
}

Then, on the login page, you should check if the user has a credential saved (you can do so by calling the $request->hasCredential() method) and, if so, displaying a button to sign in using FastLogin.

Note: Due to Apple's restrictions, you can only call the login function after a user gesture, that is, the function needs to be invoked in an user-generated event (like a "click" event).

import Cookies from 'js-cookie'
import { useLogin } from '@web-auth/webauthn-helper'

const onClick = () => {
    const token = Cookies.get('XSRF-TOKEN')

    useLogin({
        actionUrl: route('fastlogin.login'),
        optionsUrl: route('fastlogin.login.details'),
        actionHeader: {
            'x-xsrf-token': token
        },
    }, {
        'x-xsrf-token': token
    })().then(() => {
        // the user has been logged in

        window.location.reload()
    })
}

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

laravel-fastlogin's People

Contributors

captenmasin avatar chrisrenga avatar danclaytondev avatar dirk-helbert avatar fredbradley avatar ltkort avatar m1guelpf avatar simoneu01 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-fastlogin's Issues

Not working in Laravel 8 + Vue && also getting Internal server error on laravel 6.0 too.

Hello, I am trying to integrate this package with Laravel 8. When I tried to add the package for laravel-fastlogin, I'm Getting conflict errors as shown below.

image

Also, I have tried with "Carnival_panel" cloned which is mentioned in the Used By section of this package Github repo. there I have made some changes and tried to call the useLogin() function with necessary params. but this is also not working properly. getting "Internal server error". Please check the below Screenshot.

image

Could you please do needful on this!

Thanks.

bug: invalid byte sequence for encoding postgres

My only change is the use of uuid instead of bigint in the migration:

Schema::create('webauthn_credentials', function (Blueprint $table) {
    $table->id();
    $table->foreignIdFor(User::class)->constrained()->cascadeOnDelete();
    $table->binary('credId');
    $table->binary('key');
    $table->timestamps();
});

Right after confirm with TouchID:

[2021-11-08 11:57:44] production.DEBUG: No attestation is asked.
[2021-11-08 11:57:44] production.DEBUG: The Attestation Statement is anonymous.
[2021-11-08 11:57:44] production.ERROR: An error occurred {"exception":"[object] (Illuminate\Database\QueryException(code: 22021): SQLSTATE[22021]: Character not in repertoire: 7 ERROR: invalid byte sequence for encoding "UTF8": 0x85 (SQL: select * from "webauthn_credentials" where "credId" = �-�?\u0001��Kzʎw��cg��k� limit 1) at /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php:703)
[stacktrace]
#0 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php(663): Illuminate\Database\Connection->runQueryCallback()
#1 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Connection.php(367): Illuminate\Database\Connection->run()
#2 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2350): Illuminate\Database\Connection->select()
#3 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2338): Illuminate\Database\Query\Builder->runSelect()
#4 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2872): Illuminate\Database\Query\Builder->Illuminate\Database\Query\{closure}()
#5 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php(2339): Illuminate\Database\Query\Builder->onceWithColumns()
#6 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(615): Illuminate\Database\Query\Builder->get()
#7 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php(599): Illuminate\Database\Eloquent\Builder->getModels()
#8 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Database/Concerns/BuildsQueries.php(259): Illuminate\Database\Eloquent\Builder->get()
#9 /data/wwwroot/app/vendor/m1guelpf/laravel-fastlogin/src/Utils/CredentialSource.php(16): Illuminate\Database\Eloquent\Builder->first()
#10 /data/wwwroot/app/vendor/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php(204): M1guelpf\FastLogin\Utils\CredentialSource->findOneByCredentialId()
#11 /data/wwwroot/app/vendor/m1guelpf/laravel-fastlogin/src/Http/Controllers/FastLoginController.php(58): Webauthn\AuthenticatorAttestationResponseValidator->check()
#12 /data/wwwroot/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(48): M1guelpf\FastLogin\Http\Controllers\FastLoginController->create()

Package version incompatibilities

The package is not compatible with laravel 9 and php version 8.1
Illuminate 8 version needs to be updated to the latest

{
    "name": "m1guelpf/laravel-fastlogin",
    "description": "Allow your users to login with FaceID/TouchID",
    "keywords": [
        "m1guelpf",
        "laravel-fastlogin"
    ],
    "homepage": "https://github.com/m1guelpf/laravel-fastlogin",
    "license": "MIT",
    "authors": [
        {
            "name": "Miguel Piedrafita",
            "email": "[email protected]",
            "role": "Developer",
            "homepage": "https://miguelpiedrafita.com"
        }
    ],
    "require": {
        "php": "^8.0|^8.1",
        "illuminate/contracts": "^9.31",
        "illuminate/database": "^9.31",
        "illuminate/http": "^9.31",
        "illuminate/support": "^9.31",
        "illuminate/validation": "^9.31",
        "nyholm/psr7": "*",
        "psr/http-message": "*",
        "symfony/psr-http-message-bridge": "*",
        "web-auth/webauthn-lib": "*"
    },
    "autoload": {
        "psr-4": {
            "M1guelpf\\FastLogin\\": "src"
        }
    },
    "scripts": {
        "psalm": "vendor/bin/psalm",
        "cs": "php-cs-fixer fix . --config=.php_cs --allow-risky=yes"
    },
    "config": {
        "sort-packages": true
    },
    "extra": {
        "laravel": {
            "providers": [
                "M1guelpf\\FastLogin\\FastLoginServiceProvider"
            ]
        }
    },
    "minimum-stability": "dev",
    "prefer-stable": true
}

Cookie not available in FastLoginController.php

I'm creating a new issue here because I butchered the last one

Registering a key/credential is fine and I can see the X-FastLogin cookie exists when viewing in inspect element however when trying to login with the auth details, I get a 500 error. I dug around a little and it seems (for whatever reason) the X-FastLogin cookie is not available and I get this error

message: "Webauthn\\PublicKeyCredentialDescriptor::__construct(): Argument #2 ($id) must be of type string, null given, called in /{site directory}/vendor/m1guelpf/laravel-fastlogin/src/Http/Controllers/FastLoginController.php on line 78"

I tried DD-ing the cookie in FastLoginController.php and the cookie just seems to be null

Screenshot 2021-07-05 at 1 45 45 pm

Screenshot 2021-07-05 at 1 46 01 pm

Screenshot 2021-07-05 at 1 46 15 pm

Improve documentation to show complete example?

I'm a seasoned PHP programmer, but fairly new to Laravel, and I started trying to implement this seemingly super cool package, but I couldn't get very far. It would be nice to have more thorough instructions for us folks newer to Laravel. Although I could follow the instructions for yarn add after switching to npm, and the instructions for updating the model/User.php, I couldn't figure out what to do after To get started, you need to have the user register a new credential. You can do so by presenting them with a modal when they login, or by adding the option to their settings page. I'm using jetstream, so I have a settings page and login page, but it is a mystery where the code-blocks should go.

So, where should I put this block (for a typical installation)?

import Cookies from 'js-cookie'
import { useRegistration } from '@web-auth/webauthn-helper'

const onClick = () => {
    const token = Cookies.get('XSRF-TOKEN')

    useRegistration({
        actionUrl: route('fastlogin.create'),
        optionsUrl: route('fastlogin.create.details'),
        actionHeader: {
            'x-xsrf-token': token
        },
    }, {
        'x-xsrf-token': token
    })().then(() => {
        // credential has been added
    })
}

And where should I put this block?

import Cookies from 'js-cookie'
import { useLogin } from '@web-auth/webauthn-helper'

const onClick = () => {
    const token = Cookies.get('XSRF-TOKEN')

    useLogin({
        actionUrl: route('fastlogin.login'),
        optionsUrl: route('fastlogin.login.details'),
        actionHeader: {
            'x-xsrf-token': token
        },
    }, {
        'x-xsrf-token': token
    })().then(() => {
        // the user has been logged in

        window.location.reload()
    })
}

I would love to see a simple tutorial, or sample git repository, of modifying a fresh jetstream install to use this package.

But this seems like a neat package my users would appreciate.

PHP 7 Support

i have some errors.
(Package m1guelpf/laravel-fastlogin at version has a PHP requirement incompatible with your PHP version, PHP extensions and Composer version)

my php version: 7.4.9
my composer version: 2.0.0-RC1
my laravel application version: 7.30.1

Creation Error caused by multiple Session ID's

It gives a 500 error on where it creates a 'CacheKey':

return 'fastlogin-request-'.sha1(request()->getHttpHost().session()->getId());

On dumping the session ID, while creating the key, it dumps multiple different keys. The cause is the session ID. It changes per request. When I switch it to:

protected function getCacheKey()
    {
         return 'fastlogin-request-'.sha1(request()->getHttpHost().request()->session()->token());
    }

Source: Laravel Docs

It does seem to work correctly..

Issue with migration

I could not migrate without renaming migration class to "CreateCredentialsTable". Don't know if this bug is just for me or for everyone. I have Laravel v8. Please check it out. I think it is because migration name, and class differance.
BTW Great Package. Thank you.
Capture

decodeNoPadding() doesn't tolerate padding

Hi, thanks for the package. I tried to get it to work (v2.2) with Laravel 9.52.4 and hit the issue described here: web-auth/webauthn-framework#285

A quick check revealed, that web-auth/webauthn-helper is indeed archive and it is recommended to switch to SimpleWebAuthn.

Any plans to witch to SimpleWebAuthn in the near future?

Btw. I tried to use SimpleWebAuthn as a drop in replacement for webauthn-helper, using the code in their docs, but got stuck with the error:

Invalid input. "attestation" is missing.

Couldn't figure that one out ...

php version

is there a work around to let it work with php 8.0, since webauthn library requires 8.1

Credential Options are stored in the Cache based on IP

During the registration process, the PublicKeyCredentialCreationOptions are created for the desired user and send to the browser to register a key. They are then stored in the cache, for validating the registration process (the server needs to keep the creation options stored).
The options are stored in the cache keyed like this:

protected function getCacheKey()
{
    return 'fastlogin-request-'.sha1(request()->getHttpHost().request()->ip());
}

The cache is the same across all users, and this keys on IP, so if two users were registering or logging in at the same time (within 5 minutes) in a house/office/cafe where the ip is not unique, then it is very possible that cache will return the options for the wrong user, and the registration will fail for both users.
Note, I don't think there is any security risk, as the options are never returned from the cache to the users but I do think it could fail registration for both of them. If is certainly possible that two users in an office might be logging in at the same time.

Is there any reason that we can't store the creation/login options in the session? The session is what Jetstream/Fortify uses for two factor authentication challenges.

I'm really excited to use this package, so if there is no problem with the session, I would be happy to have a go at a PR. :)

Getting CSRF token mismatch error

Normal ajax call working fine on that page but useLogin giving csrf error.

my code as:

        //const token = $('meta[name="csrf-token"]').attr('content');
        const token = Cookies.get('XSRF-TOKEN');
        
        useLogin({
                actionUrl: 'http://localhost:8000/fastlogin/login',
                optionsUrl: 'http://localhost:8000/fastlogin/login/details',
                actionHeader: {
                    'x-xsrf-token': token
                },
            }, {
                'x-xsrf-token': token
            })().then(() => {
                // credential has been added
                console.log('credential has been added.');
            })

Is there anything wrong ?

Webauthn\\PublicKeyCredentialDescriptor::__construct() must be of the type string, null given

I am getting some errors on this package implementation. Have you any idea, where is my mistate ?

on fastlogin/login/details:
Argument 2 passed to Webauthn\PublicKeyCredentialDescriptor::__construct() must be of the type string, null given, called in D:\laragon\www\face-test\vendor\m1guelpf\laravel-fastlogin\src\Http\Controllers\FastLoginController.php on line 114 at D:\laragon\www\face-test\vendor\web-auth\webauthn-lib\src\PublicKeyCredentialDescriptor.php:49)

\Log::info($request->cookie(FastLoginServiceProvider::FASTLOGIN_COOKIE));
it's showing null

And console showing:
TypeError: Cannot read properties of undefined (reading 'replace')
at base64UrlDecode (app.js:60:8)
at preparePublicKeyOptions (app.js:81:7)

And my js code:

                const token = $('meta[name="csrf-token"]').attr('content');  
                useLogin({
                    actionUrl: 'http://127.0.0.1:8000/fastlogin/login',
                    optionsUrl: 'http://127.0.0.1:8000/fastlogin/login/details',
                    actionHeader: {
                        'X-CSRF-TOKEN': token
                    },
                    optionsHeader: {
                        'X-CSRF-TOKEN': token
                    }
                }, {
                    'X-CSRF-TOKEN': token
                })().then((response) => {
                    //window.location.reload()
                    console.log(response + ', Login successful.');
                })
                .catch((error) => console.log(error, 'Login failed.'));

loginValidator->check fails

Am trying to add this to an application. But the $loginValidator->check keeps failing.

Currently i am testing it by sharing site via Expose. Is there any reason that this might cause the validator check problems?

TypeError: Cannot read property 'create' of undefined

                import Cookies from 'js-cookie'
                import { useRegistration } from '@web-auth/webauthn-helper'
                ---
                ---
                onclick(){
                         const token = Cookies.get('XSRF-TOKEN')
                         useRegistration({
                              actionUrl: route('fastlogin.create'),
                              optionsUrl: route('fastlogin.create.details'),
                              actionHeader: {
                                  'x-xsrf-token': token
                             },
                         }, {
                            'x-xsrf-token': token
                        })().then(() => {
                                 this.$page.props.jetstream.flash.banner = 'Face/Touch ID credentials have been added.'
                        },err=>{
                           alert(err);//getting  " cannot read property 'create' of undefined" error here 
                         })
                }

Working fine in iphone and getting error while i try to use in android device

Cookie not available in JS or Laravel

I've just installed the package on a fairly simple Laravel app however after setting up and enabling fastlogin, when I try to login it can't seem to access the "X-FastLogin" cookie, either in the actual JS or when dd-ing $request

Screenshot 2021-07-02 at 9 39 09 pm

I can see that it's there in the cookies section of inspect element but if I run alert(Cookies.get('X-FastLogin')) on click, it returns undefined

Screenshot 2021-07-02 at 9 41 00 pm

Screenshot 2021-07-02 at 9 41 07 pm

Not compatible with Laravel?

The latest version is not compatible with the Laravel Framwork since it gets package conflicts from a clean slate installation.
Laravel Framework 8.82 using Laravel Installer 8.6.10

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - m1guelpf/laravel-fastlogin[v2.0, ..., v2.0.2] require web-auth/webauthn-lib ^3.3 -> satisfiable by web-auth/webauthn-lib[v3.3.0, ..., v3.3.x-dev].
    - web-auth/webauthn-lib[v3.3.0, ..., v3.3.x-dev] require psr/log ^1.1 -> found psr/log[1.1.0, ..., 1.1.4] but the package is fixed to 2.0.0 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.
    - Root composer.json requires m1guelpf/laravel-fastlogin ^2.0 -> satisfiable by m1guelpf/laravel-fastlogin[v2.0, v2.0.1, v2.0.2].

Use the option --with-all-dependencies (-W) to allow upgrades, downgrades and removals for packages currently locked to specific versions.
You can also try re-running composer require with an explicit version constraint, e.g. "composer require m1guelpf/laravel-fastlogin:*" to figure out if any version is installable, or "composer require m1guelpf/laravel-fastlogin:^2.1" if you know which you need.

Cookies removed

Hello!

First, thanks for this amazing package 😄

How can we handle if user deletes the cookies? Cause If they try again to login again with the same method, an error is throw.

Will be great to add the cookies again if the system detects that the device has the authorization.

Any ideas?

Thanks!

Remove authorisation

If a user changes their mind and wants to remove the biometric login, how can I remove that?

Thanks,

Laravel Breeze

Shouldnt the package be compatible with Laravel Breeze?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.