All Projects β†’ erdemkeren β†’ laravel-otp

erdemkeren / laravel-otp

Licence: MIT license
A laravel package to protect your routes with one time passwords (otp)

Programming Languages

PHP
23972 projects - #3 most used programming language
shell
77523 projects
Blade
752 projects

Projects that are alternatives of or similar to laravel-otp

gpkg
🌎 A global Node binary manager written in Rust
Stars: ✭ 53 (-63.95%)
Mutual labels:  package
publish
Publish your module with one command in Deno.
Stars: ✭ 16 (-89.12%)
Mutual labels:  package
Flogs
An Advanced Logging Framework develop in flutter that provides quick & simple logging solution.
Stars: ✭ 158 (+7.48%)
Mutual labels:  package
app-version-laravel
Laravel application versioning
Stars: ✭ 24 (-83.67%)
Mutual labels:  package
hotp-php
HMAC Based One Time Passwords in PHP. RFC4226 and RFC6238 compliant.
Stars: ✭ 51 (-65.31%)
Mutual labels:  otp
laravel-web-push
Laravel package for sending out push notifications
Stars: ✭ 14 (-90.48%)
Mutual labels:  package
multiOTPCredentialProvider
multiOTP Credential Provider is a V2 Credential Provider for Windows 7/8/8.1/10/2012(R2)/2016 with options like RDP only and UPN name support
Stars: ✭ 121 (-17.69%)
Mutual labels:  otp
R.devices
🎨 R package: Unified Handling of Graphics Devices
Stars: ✭ 17 (-88.44%)
Mutual labels:  package
abacus
Abacus is a tool to simplify the handling of units
Stars: ✭ 22 (-85.03%)
Mutual labels:  otp
jean
Bored from installing tiny shell scripts and .dotfiles manually? Huh! Missing Shell Package Manager For Linux
Stars: ✭ 21 (-85.71%)
Mutual labels:  package
laration
Simple package to see all current configurations being used by your Laravel application
Stars: ✭ 47 (-68.03%)
Mutual labels:  package
cft
Climate futures toolbox: easy MACA (MACAv2) climate data access πŸ“¦
Stars: ✭ 16 (-89.12%)
Mutual labels:  package
module-init
🏁 Create a new node module with all the right stuff.
Stars: ✭ 71 (-51.7%)
Mutual labels:  package
dataset
qri dataset definition
Stars: ✭ 16 (-89.12%)
Mutual labels:  package
MGM-Ability
No description or website provided.
Stars: ✭ 64 (-56.46%)
Mutual labels:  package
otp
πŸ“« Fault tolerant multicore programs with actors
Stars: ✭ 169 (+14.97%)
Mutual labels:  otp
cre
common runtime environment for distributed programming languages
Stars: ✭ 20 (-86.39%)
Mutual labels:  otp
metric.js
ianramosc.github.io/metric.js
Stars: ✭ 29 (-80.27%)
Mutual labels:  package
R.oo
R package: R.oo - R Object-Oriented Programming with or without References
Stars: ✭ 19 (-87.07%)
Mutual labels:  package
ios-application
A native, lightweight and secure one-time-password (OTP) client built for iOS; Raivo OTP!
Stars: ✭ 581 (+295.24%)
Mutual labels:  otp

Laravel OTP

Latest Version on Packagist Software License Build Status StyleCI Quality Score Code Coverage Total Downloads

This package allows you to secure your resources with one time password access (otp).

Example Usage:

Route::get('secret', function (\Illuminate\Http\Request $request): string {
    $token = $request->otpToken();
    $messages[] = "The otp token {$token} has {$token->timeLeft()} out of {$token->expiryTime()} seconds.";

    $token->refresh();
    $messages[] = "The time left can be reset using the refresh method: {$token->timeLeft()}/{$token->expiryTime()}";

    $token->extend(30);
    $messages[] = "The expiry time can be increased using the extend method: {$token->timeLeft()}/{$token->expiryTime()}";

    $messages[] = "You can also invalidate the token immediately. Try refreshing the page ;)";
    $request->otpToken()->invalidate();

    return implode('<br>', $messages);
})->middleware('auth', 'otp');

Contents

Installation

1- Add the package to your dependencies.

$ composer require erdemkeren/laravel-otp;

2- Register the package in your config/app.php file:

only if you your auto package discovery off.

Erdemkeren\Otp\OtpServiceProvider::class,

3- Publish the components:

Publishes a migration, two views and a configuration file.

$ php artisan vendor:publish

4- Apply the migrations:

Will create a table called otp_tokens to store generated token information.

$ php artisan migrate

5- Register the routes:

These routes are required if you are planning to use otp middleware.

In your RouteServiceProvider, append the following line inside the map method:

// App\RouteServiceProvider@map:
\Erdemkeren\Otp\OtpRoutes::register();

6- Register the route middleware:

Register the otp route middleware inside your App\Http\Kernel.

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    // [...]
    'otp' => \Erdemkeren\Otp\Http\Middleware\Otp::class,
];

Configuration

This package comes with a set of handy configuration options:

password_generator: The password generator option allows you to decide which generator implementation to be used to generate new passwords.

Available built-in options: string, numeric and numeric-no-0. default: string

table: The name of the table to be used to store the otp tokens.

default: otp_tokens

expiry_time: The expiry time of the tokens in minutes.

default: 15

default_channels: The default notification channels of the token notification.

Usage

Basic Usage

After configuring your instance of the package, you can use the built-in otp middleware alias to secure your endpoints:

Route::get('secret', function (Request $request): string {
    $request->otpToken()->refresh();

    return 'The secret of immortality';
})->middleware('auth', 'otp');

This middleware will redirect any unauthenticated request to the otp/create endpoint which we have registered in the installation process:

  • A password will be generated using the configured password generator.
  • The authenticated user will be notified about the password via the configured notification channel.
  • The user will see a form to submit their password.
  • You can change the appearance of the view under your resources/views/otp directory, modifying create.blade.php file.
  • After a successful authentication; the user will be redirected back to the original route they requested at the first step.
  • The redirected request will also include the otpToken() instance being used by the user.

Advanced Usage

Adding the notification channel method:

If you are not using the mail channel, or your notification channel is expecting a method different than mail or sms, you can register your own method like:

// AppServiceProvider::register():
TokenNotification::macro('AcmeSms', function () {
    // $this is TokenNotification class.
    return $this->notification->code;
});

Don't forget to change your configuration file as well.

Using your own password generator:

To add your own password generator implemetation, you can call addPasswordGenerator method on Otp service like:

// AppServiceProvider::register():
app('otp')->addPasswordGenerator('acme', function (int $length): string {
    return 'your_implementation';
});

If you need more power, you can also create your own password generator class too:

<?php namespace App\Acme\PasswordGenerators;

use Erdemkeren\Otp\PasswordGeneratorInterface;

class AcmePasswordGenerator implements PasswordGeneratorInterface
{
    /**
     * Generate an acme password with the given length.
     *
     * @param  int    $length
     * @return string
     */
    public function generate(int $length): string
    {
        return 'your implementation';
    }
}

You can register you password generator like the previous one:

// AppServiceProvider::register():
Otp::addPasswordGenerator('acme', AcmePasswordGenerator::class);

Don't forget to change your configuration file as well.

Determining the otp channel per notifiable

The Notification class checks otpChannels existence inside the notifiable being notified. If so, this method is being called to determine which notification channel is going to be used to notify the notifiable.

Deeper Knowledge:

The public API consists of two main components: OtpService and the Token which generally is being returned by the service.

Otp Service:

If you are planning to create your own API or the basic functionality is not enough four you, you can use the Otp Service API:

Chencking the validity of a given token:
$isTokenValid = Otp::check($authenticableId, $token);
Setting the password generator:
Otp::setPasswordGenerator('string');
Creating a new token for a given user:
$token = Otp::create(auth()->user(), $length = 6);
// See what can be done with tokens below.
Retrieveing an existing token from the storage by the given plain password:
$token = Otp::retrieveByPlainText(auth()->id(), $otpPassword);
// See what can be done with tokens below.
Retrieveing an existing token from the storage by the given cipher text (token):
$token = Otp::retrieveByCipherText(auth()->id(), $otpPassword);
// See what can be done with tokens below.
Changing the behavior of the Service

The package comes with a ServiceProvider which registers the Otp service to your application's container.

The Otp orchestrates the method calls made to the 3 interface implementations below.

  • PasswordGeneratorManagerInterface
  • EncryptorInterface and
  • TokenInterface

You can write your service provider and register the OtpService with your version of the dependencies.

Note: Because the token class is being used with static calls, you have to send the fully qualified name of your TokenInterface implementation.

Token API:

Getting the attributes of the token:
public function authenticableId();
public function cipherText(): string;
public function plainText(): ?string; // If you have just created the token, plain text will be accessable. If you retrieved it; it won't.
public function createdAt(): Carbon;
public function updatedAt(): Carbon;
public function expiryTime(): int;
public function expiresAt(): Carbon;
public function timeLeft(): int;
public function expired(): bool;
Invalidate a token:
public function revoke(): void;
public function invalidate(): void;

e.g.

public function show(Request $request, $id) {
    if($request->input('revoke_session', false)) {
        $request->otpToken()->revoke();
    }

    return view('heaven');
}
Extend or refresh the token expiry time:
// Extend the usage time of the token for the given seconds:
public function extend(?int $seconds = null): bool;
// Make the token function like it has just been created:
public function refresh(): bool;

e.g.

$token = Otp::retrieveByCipherText(
    auth()->id(),
    $request->input('otp_token')
);

if(! $token->expired()) {
 $token->refresh();
}
Create a new token:
public static function create(
    $authenticableId,
    string $cipherText,
    ?string $plainText = null
): TokenInterface;

e.g.

$token = Token::create(1, 'foo', 'plain foo');
Retrieve a token from the storage by the given attributes:

Make sure that the attributes you provided will return a unique token.

public static function retrieveByAttributes(array $attributes): ?TokenInterface;

e.g.

$token = Token::retrieveByAttributes([
    'authenticable_id' => 1,
    'cipher_text'      => 'foo',
]);
Convert the token to a notification:
public function toNotification(): Notification;

e.g.

$user->notify($token->toNotification());

Changelog

Please see CHANGELOG for more information what has changed recently.

Testing

$ composer test

Credits

  • Hilmi Erdem KEREN
  • Berkay GΓΌre

SymfonyInsight

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].