adeshsuryan/laravel-otp-login

为Laravel内置认证系统添加OTP登录步骤

5.13 2019-07-28 09:40 UTC

This package is auto-updated.

Last update: 2024-09-28 21:21:15 UTC


README

此包在成功使用默认认证机制登录后提供一次性密码检查步骤。该包将所有请求的一次性密码及其验证状态存储在one_time_passwordsone_time_password_logs表中。

它使用本包中包含的中件检查用户是否通过了OTP检查或当前认证状态。

致谢

此包基于tpaksu/laravel-otp-login包的想法。REST API与控制器策略是由我开发的。

要求

安装

您可以使用Composer在现有的Laravel项目中安装此包

 $ composer require adeshsuryan/laravel-otp-login

然后,通过编辑config/app.php文件并添加到提供者数组中,注册OTP Login ServiceProvider

  adeshsuryan\LaravelOTPLogin\OTPServiceProvider::class,

注意:对于Laravel <5.1版本,请使用以下方法

 'adeshsuryan\LaravelOTPLogin\OTPServiceProvider',

使用以下命令发布文件:

 $ php artisan vendor:publish --provider="adeshsuryan\LaravelOTPLogin\OTPServiceProvider"

或者,只需使用php artisan vendor:publish,并从输出列表中选择adeshsuryan\LaravelOTPLogin\OTPServiceProvider

应用OneTimePasswordOneTimePasswordLogs表的迁移

 $ php artisan migrate

配置

此包在您的应用程序的config文件夹中发布一个otp.php文件,其中包含此包的设置。大多数变量都绑定到环境变量,但您可以直接编辑此文件或将配置键添加到.env文件中。

此行显示服务是否启用

'otp_service_enabled' => true,

在此行中,您可以配置系统将用于发送OTP短信的默认SMS服务

'otp_default_service' => env("OTP_SERVICE", "nexmo"),

目前,此包中预定义的服务是NexmoTwilioBioTekno,但很容易将自定义服务添加到此包中。将在服务部分的文档中详细说明。

'services' => [
    'biotekno' => [
        "class" => \adeshsuryan\LaravelOTPLogin\Services\BioTekno::class,
        "username" => env('OTP_USERNAME', null),
        "password" => env('OTP_PASSWORD', null),
        "transmission_id" => env('OTP_TRANSMISSION_ID', null)
    ],
    'nexmo' => [
        'class' => \adeshsuryan\LaravelOTPLogin\Services\Nexmo::class,
        'api_key' => env("OTP_API_KEY", null),
        'api_secret' => env('OTP_API_SECRET', null),
        'from' => env('OTP_FROM', null)
    ],
    'twilio' => [
        'class' => \adeshsuryan\LaravelOTPLogin\Services\Twilio::class,
        'account_sid' => env("OTP_ACCOUNT_SID", null),
        'auth_token' => env("OTP_AUTH_TOKEN", null),
        'from' => env("OTP_FROM", null)
    ],
     'msg91' => [
         'class' => \adeshsuryan\LaravelOTPLogin\Services\Msg91::class,
         'api_key' => env("OTP_API_KEY", null),
         'sender' => env('OTP_API_SENDER',null),
         'route' => env('OTP_ROUTE', '4'),
          'country' => env('OTP_COUNTRY', '0'),
     ]
],

这一点非常重要。服务期望您在users表或相关表中有一个电话字段,以便向用户发送短信。如果用户的电话号码在users表中,您可以直接将字段名写入此设置。

'user_phone_field' => 'phone',

否则,如果它在像user_phones这样的表中,该表与您的users表相关联,您可以使用以下链接设置

'user_phone_field' => 'user_phone.phone',

此行显示生成的一次性密码参考号的长度。有关限制,请参阅otp_digit_length设置说明。它目前不用于短信,但已生成并保存到数据库中。在以后的版本中,我计划将其实现到服务中。

'otp_reference_number_length' => 6,

这定义了OTP有效期,目前设置为3个月。

'otp_timeout' => 7890000,

此行显示生成的一次性密码的长度。由于32位机器上的PHP整数限制为232(2,147,483,647),它应该小于10。在以后的版本中,它将更加可配置,但出于UX原因,我认为不需要超过10位。

'otp_digit_length' => 6,

视图

此包将一个名为 otpvalidate.blade.php 的视图发布到 resources/views/vendor/laravel-otp-login 文件夹,其中包含OTP验证界面。此视图中使用的字符串也由该包中发布的语言文件获取,因此如果您想更改此视图中的字符串,您可以在语言文件中更改它。

翻译

此包将翻译发布到 resources/lang/vendor/laravel-otp-login 文件夹,该包将土耳其语和英语作为 php 文件发布,您可以使用英语语言文件作为模板将其翻译成更多语言。以下为英语文件的示例内容

<?php return [
    "verify_phone_title" => "Verify Your Phone Number",
    "verify_phone_button" => "Verify",
    "one_time_password" => "One Time Password (OTP)",
    "hero_text" => "Thanks for giving your details. An OTP has been sent to your Mobile Number. Please enter the :digit digit OTP below for Successful Login",
    "cancel_otp" => "Nevermind, take me back to the login page.",
    "otp_expired" => "Your OTP code seems to be expired. Please login again to get a new OTP code.",
    "unauthorized" => "You are not allowed to do this.",
    "code_missing" => "The OTP field should exist and be filled.",
    "code_mismatch" => "The code doesn't match to the generated one. Please check and re-enter the code you received.",
    "otp_message" => "Your one-time password to enter the system is: :password",
    "otp_not_received" => "Didn't receive the password? Log out and try again!",
    "service_not_responding" => "SMS service currently seems to be not responding. Please try again."
];

服务

包含的服务

BioTekno

BioTekno 是我最初用于为我公司开发此包的服务,因此我决定将其保留在此。该服务使用 GET 请求发送短信,需要用户名/密码组合和一个传输ID,该ID用作代替手机号显示在客户移动设备上的名称。它使用 adeshsuryan\LaravelOTPLogin\Services\BioTekno 类发送消息。

    'biotekno' => [
        "class" => \adeshsuryan\LaravelOTPLogin\Services\BioTekno::class,
        "username" => env('OTP_USERNAME', null),
        "password" => env('OTP_PASSWORD', null),
        "transmission_id" => env('OTP_TRANSMISSION_ID', null)
    ],

Nexmo

Nexmo 似乎是一种流行的消息服务,因为我对短信服务不太熟悉,但它有一个易于使用的API,因此我决定在包中实现它。它有自己的composer包,可以在Laravel或其他PHP系统中使用,但由于我只想发送短信,所以我直接在此包中实现了他们的REST API解决方案。

此服务为您提供了常见的API认证参数 api_keyapi_secret,但您还需要一个电话号码(同样由Nexmo提供)作为发送地址。这些参数足以配置服务。它使用 adeshsuryan\LaravelOTPLogin\Services\Nexmo 类发送消息。

    'nexmo' => [
        'class' => \adeshsuryan\LaravelOTPLogin\Services\Nexmo::class,
        'api_key' => env("OTP_API_KEY", null),
        'api_secret' => env('OTP_API_SECRET', null),
        'from' => env('OTP_FROM', null)
    ],

Twilio

Twilio 同样是最受欢迎的消息服务之一,除了短信消息外,还提供语音通话、社交消息和视频通话。它也有自己的库,可以在多个基于PHP的框架/软件(如Laravel)中使用,但我仍然选择了简单的方法,只实现了发送消息的REST API样式。如果您查看 adeshsuryan\LaravelOTPLogin\Services\Twilio 的源代码,您会理解。

Twilio服务在您完成注册并创建短信项目后,在控制台为您提供 account_sidauth_token。然后您需要一个类似Nexmo的电话号码,使用这些信息向您的“已验证”号码发送短信。您还需要在控制台上启用您希望发送消息的国家。否则,您将收到一个错误,表明该国家不允许发送短信。对于 from 配置参数,您需要填写从服务中获得的电话号码。

    'twilio' => [
        'class' => \adeshsuryan\LaravelOTPLogin\Services\Twilio::class,
        'account_sid' => env("OTP_ACCOUNT_SID", null),
        'auth_token' => env("OTP_AUTH_TOKEN", null),
        'from' => env("OTP_FROM", null)
    ]

编写您自己的服务

服务类具有以下结构

<?php

// the package namespace, you won't be using it
// because you'll generate your service in the App\OTPService directory
namespace adeshsuryan\LaravelOTPLogin\Services;

// - OR if you are writing your service in App\OTPServices folder
namespace App\OTPServices;

// Your user instance, change it if you are using a different model
use App\User;

// this is a must.
use adeshsuryan\LaravelOTPLogin\ServiceInterface;

// the class name definition
class MyMessagingService implements ServiceInterface
{
    // this is where you define the global variables which you
    // fetch in the constructor to use in the method ;)

    private $api_key;
    private $phone_column;
    private $message;

    /**
     * constructor
     */
    public function __construct()
    {
        // this is where you get the global variables inside the class
        // - OR -
        // you might fetch them directly inside the sendOneTimePassword

        $this->api_key = config("otp.services.mymsgservice.api_key", null);
        $this->message = trans('laravel-otp-login::messages.otp_message');
        $this->phone_column = config('otp.user_phone_field');
    }

    /**
     * Sends the generated password to the user and returns if it's successful
     *
     * @param App\User $user : The user to send the OTP to
     * @param string $otp    : The One Time Password
     * @param string $ref    : The reference number of this request
     * @return boolean
     */
    public function sendOneTimePassword(User $user, $otp, $ref)
    {
        // this is where you send the $otp password SMS to the $user
        // get the phone number
        $phone_number = data_get($user, $this->phone_column, false);
        // if phone number doesn't exists return
        if($phone_number == false) return false;

        try {
            // send the SMS to the phone number here
            // get the response and if the transmission is succeeded return true,
            // otherwise return false
            return $result;
        }
        catch(\Exception $ex)
        {
            // always return false if something is wrong.
        }
    }
}

修改现有服务

如果您需要修改此包中包含的服务,您可以检查您的 App\OTPServices 文件夹,您将在此文件夹中看到每个服务类的副本。将命名空间从 adeshsuryan\LaravelOTPLogin\Services 更改为 App\OTPServices,并在配置文件中将类路径更改为修改后的文件。这将足够使用此类的修改版本。

许可证

MIT许可证 (MIT)

版权所有 (c) 2018

本软件及其相关文档文件(统称为“软件”)的副本获取者,在此免费授予不受限制地处理软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或销售软件副本的权利,以及允许获得软件的人进行此类操作,但须遵守以下条件:

上述版权声明和本许可声明应包含在软件的所有副本或实质性部分中。

软件按“原样”提供,不提供任何形式的保证,无论是明示的还是隐含的,包括但不限于适销性、特定用途适用性和非侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论这些索赔、损害或其他责任是因合同行为、侵权行为或其他原因引起的,无论是否与软件或软件的使用或其他使用有关。