如何在Laravel后端和Vue.js前端中实现OTP认证以确保交易安全?

AI 概述
本文主要介绍了在 Laravel 后端和 Vue.js 前端实现 OTP 认证的方法。先阐述使用 OTP 认证的原因及先决条件,接着说明设置步骤,包括安装 Laravel 和所需包、配置邮件服务、创建邮件类和控制器;创建用于 OTP 输入的 Vue.js 组件,设置相关路由与控制器方法;最后将 OTP 认证集成到登录和注册工作流程中,如更新登录、注册控制器。实现 OTP 认证能为金融应用等增强安全性,防止未经授权访问。
目录
文章目录隐藏
  1. 为什么使用一次性密码(OTP)认证?
  2. 先决条件
  3. 设置 Laravel 用于 OTP 认证
  4. 结语

如何在 Laravel 后端和 Vue.js 前端中实现 OTP 认证以确保交易安全?

在当今的数字世界中,数据安全性是至关重要的,特别是在处理用户身份验证和金融交易等敏感数据时。增强安全性最有效的方法之一是实施一次性密码(OTP)认证。本文探讨了如何在 Laravel 后端和 Vue.js 前端中实现 OTP 认证,以确保交易的安全性。

为什么使用一次性密码(OTP)认证?

OTP 认证在传统用户名和密码认证之外提供了额外的安全层。

一些主要优点包括:

  • 防止未经授权的访问: 即使登录凭证被泄露,攻击者没有 OTP 也无法登录。
  • 交易增强安全性: OTPs 可用于确认高价值交易,防止欺诈。
  • 临时有效性: 由于一次性口令(OTP)在短时间内就会过期,因此它们减少了被攻击者重复使用的风险。

先决条件

在开始之前,请确保您拥有以下内容:

  • Laravel 8 或更高版本已安装
  • Vue.js 已在您的项目中配置
  • 用于发送 OTP(例如 Twilio、Mailtrap)的邮件或短信服务提供商
  • 对 Laravel 和 Vue.js 的基本理解

在本教程中,我们将实现 Laravel(后端)和 Vue.js(前端)应用中的 OTP 认证。我们将涵盖:

  • 从头开始设置 Laravel 和 Vue (前端);
  • 在 Laravel 中设置 OTP 生成和验证;
  • 创建一个用于 OTP 输入的 Vue.js 组件;
  • 将一次性密码(OTP)认证整合到登录工作流程中;
  • 通过最佳实践增强安全性。

到结束时,我们将拥有一个完全功能的 OTP 身份验证系统,可以增强金融科技或网络应用程序的安全性。

设置 Laravel 用于 OTP 认证

步骤 1:安装 Laravel 和所需包

如果你还没有设置 Laravel 项目,请创建一个新的:

composer create-project "laravel/laravel:^10.0" example-app

接下来,安装 Laravel Breeze 包 用于前端 scaffolding:

composer require laravel/breeze --dev

composer安装完成后,运行以下命令来选择您要使用的框架——Vue 配置:

php artisan breeze:install

Breeze 会自动为你的 Laravel Vue 项目安装必要的包。你应该看到:INFO Breeze scaffolding installed successfully.

现在运行 npm 命令来构建你的前端资源:

npm run dev

然后,打开另一个终端并启动你的 Laravel 应用程序:

php artisan serve

步骤 2:在 Laravel 中设置 OTP 生成和验证

这里我们将使用 Mailtrap 的邮件测试平台来本地发送和接收邮件。如果你还没有设置邮件测试服务,请在 Mailtrap 注册以获取你的 SMTP 凭证,并将其添加到你的文件中:

MAIL_MAILER=smtp
MAIL_HOST=sandbox.smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=1780944422200a
MAIL_PASSWORD=a8250ee453323b
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@example.com
MAIL_FROM_NAME="${APP_NAME}"

为了向用户发送 OTP,我们将使用 Laravel 的内置邮件服务。创建一个邮件类和控制器:

php artisan make:mail OtpMail
php artisan make:controller OtpController

然后修改 OtpMail 类:

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;

class OtpMail extends Mailable
{
    use Queueable, SerializesModels;

    public $otp;

    /**
     * Create a new message instance.
     */
    public function __construct($otp)
    {
        $this->otp = $otp;
    }

    /**
     * Build the email message.
     */
    public function build()
    {
        return $this->subject('Your OTP Code')
            ->view('emails.otp')
            ->with(['otp' => $this->otp]);
    }

    /**
     * Get the message envelope.
     */
    public function envelope(): Envelope
    {
        return new Envelope(
            subject: 'OTP Mail',
        );
    }
}

在 resources/views/emails/otp.blade.php中创建一个 Blade 视图:

<!DOCTYPE html>
<html>
    <head>
        <title>Your OTP Code</title>
    </head>
    <body>
        <p>Hello,</p>
        <p>Your One-Time Password (OTP) is: <strong>{{ $otp }}</strong></p>
        <p>This code is valid for 10 minutes. Do not share it with anyone.</p>
        <p>Thank you!</p>
    </body>
</html>

步骤 3:创建一个用于 OTP 输入的 Vue.js 组件

通常情况下,登录或注册后,用户会被重定向到仪表板。在这个教程中,我们在允许访问仪表板之前,增加了一步使用 OTP(一次性密码)来验证用户的安全措施。

创建两个 Vue 文件:

  • Request.vue请求一次性密码 (OTP);
  • Verify.vue输入一次性密码进行验证。

现在我们创建路由,以便返回视图和创建 OTP 代码、存储 OTP 代码、通过 mail 类发送 OTP 代码,我们前往我们的 web.php 文件:

Route::middleware('auth')->group(function () {
    Route::get('/request', [OtpController::class, 'create'])->name('request');
    Route::post('/store-request', [OtpController::class, 'store'])->name('send.otp.request');

    Route::get('/verify', [OtpController::class, 'verify'])->name('verify');
    Route::post('/verify-request', [OtpController::class, 'verify_request'])->name('verify.otp.request');
});

request.vue将所有这些代码放入 OTP 控制器中,返回我们和verify.vue文件的视图以及创建 OTP 代码、存储 OTP 代码、通过邮件类发送 OTP 代码和验证 OTP 代码的功能,我们前往web.php文件来设置路由。

public function create(Request $request)
{
    return Inertia::render('Request', [
        'email' => $request->query('email', ''),
    ]);
}

public function store(Request $request)
{
    $request->validate([
        'email' => 'required|email|exists:users,email',
    ]);

    $otp = rand(100000, 999999);

    Cache::put('otp_' . $request->email, $otp, now()->addMinutes(10));

    Log::info("OTP generated for " . $request->email . ": " . $otp);

    Mail::to($request->email)->send(new OtpMail($otp));

    return redirect()->route('verify', ['email' => $request->email]);
}

public function verify(Request $request)
{
    return Inertia::render('Verify', [
        'email' => $request->query('email'),
    ]);
}

public function verify_request(Request $request)
{
    $request->validate([
        'email' => 'required|email|exists:users,email',
        'otp' => 'required|digits:6',
    ]);

    $cachedOtp = Cache::get('otp_' . $request->email);

    Log::info("OTP entered: " . $request->otp);
    Log::info("OTP stored in cache: " . ($cachedOtp ?? 'No OTP found'));

    if (!$cachedOtp) {
        return back()->withErrors(['otp' => 'OTP has expired. Please request a new one.']);
    }

    if ((string) $cachedOtp !== (string) $request->otp) {
        return back()->withErrors(['otp' => 'Invalid OTP. Please try again.']);
    }

    Cache::forget('otp_' . $request->email);

    $user = User::where('email', $request->email)->first();
    if ($user) {
        $user->email_verified_at = now();
        $user->save();
    }

    return redirect()->route('dashboard')->with('success', 'OTP Verified Successfully!');
}

置完所有代码后,我们返回request.vue文件进行设置。

<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import TextInput from '@/Components/TextInput.vue';
import { Head, useForm } from '@inertiajs/vue3';

const props = defineProps({
    email: {
        type: String,
        required: true,
    },
});

const form = useForm({
    email: props.email,
});

const submit = () => {
    form.post(route('send.otp.request'), {
        onSuccess: () => {
            alert("OTP has been sent to your email!");
            form.get(route('verify'), { email: form.email }); // Redirecting to OTP verification
        },
    });
};
</script>

<template>
    <Head title="Request OTP" />

    <AuthenticatedLayout>
        <form @submit.prevent="submit">
            <div>
                <InputLabel for="email" value="Email" />

                <TextInput
                    id="email"
                    type="email"
                    class="mt-1 block w-full"
                    v-model="form.email"
                    required
                    autofocus
                />

                <InputError class="mt-2" :message="form.errors.email" />
            </div>

            <div class="mt-4 flex items-center justify-end">
                <PrimaryButton :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
                    Request OTP
                </PrimaryButton>
            </div>
        </form>
    </AuthenticatedLayout>
</template>

设置完所有代码后,我们返回到verify.vue进行设置:

<script setup>
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import InputError from '@/Components/InputError.vue';
import InputLabel from '@/Components/InputLabel.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import TextInput from '@/Components/TextInput.vue';
import { Head, useForm, usePage } from '@inertiajs/vue3';

const page = usePage();
// Get the email from the URL query params
const email = page.props.email || '';

// Initialize form with email and OTP field
const form = useForm({
    email: email,
    otp: '',
});

// Submit function
const submit = () => {
    form.post(route('verify.otp.request'), {
        onSuccess: () => {
            alert("OTP verified successfully! Redirecting...");
            window.location.href = '/dashboard'; // Change to your desired redirect page
        },
        onError: () => {
            alert("Invalid OTP. Please try again.");
        },
    });
};
</script>

<template>
    <Head title="Verify OTP" />

    <AuthenticatedLayout>
        <form @submit.prevent="submit">
            <div>
                <InputLabel for="otp" value="Enter OTP" />

                <TextInput
                    id="otp"
                    type="text"
                    class="mt-1 block w-full"
                    v-model="form.otp"
                    required
                />

                <InputError class="mt-2" :message="form.errors.otp" />
            </div>

            <div class="mt-4 flex items-center justify-end">
                <PrimaryButton :disabled="form.processing">
                    Verify OTP
                </PrimaryButton>
            </div>
        </form>
    </AuthenticatedLayout>
</template>

步骤 4:将 OTP 认证集成到登录和注册工作流程中

更新登录控制器:

ublic function store(LoginRequest $request): RedirectResponse
{
    $request->authenticate();

    $request->session()->regenerate();

    return redirect()->intended(route('request', absolute: false));
}

更新注册控制器:

public function store(Request $request): RedirectResponse
{
    $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|string|lowercase|email|max:255|unique:' . User::class,
        'password' => ['required', 'confirmed', Rules\Password::defaults()],
    ]);

    $user = User::create([
        'name' => $request->name,
        'email' => $request->email,
        'password' => Hash::make($request->password),
    ]);

    event(new Registered($user));

    Auth::login($user);

    return redirect(route('request', absolute: false));
}

结语

在 Laravel 和 Vue.js 中实现 OTP 认证可以增强用户登录和交易的安全性。通过生成、发送和验证 OTP,我们可以增加一层保护以防止未经授权的访问。这种方法特别适用于金融应用程序和敏感的用户数据。

以上关于如何在Laravel后端和Vue.js前端中实现OTP认证以确保交易安全?的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » 如何在Laravel后端和Vue.js前端中实现OTP认证以确保交易安全?

发表回复