취미/프로그래밍

Laravel 이메일 인증코드 구현

Anything Doing OK 2024. 9. 10. 22:12

https://normal-operating.tistory.com/36 

 

Laravel 이메일 인증 연동 구현하기

회사에서 레거시만 사용하다보니 기능을 간단하게 구현할 수 있는 laravel 을 통해서 구현해보았다.  진행하면서 발생한 오류 해결방안에러 : php artisan migrate ( php_network_getaddresses: getaddrinfo failed:

normal-operating.tistory.com

으로 구현했는데 요즘 웹사이트 가면 인증번호 날아오고 그 코드를 쓰면 인증 완료 후 가입이 되는데 위 방식은 요즘 트렌드에 맞지 않아서 새롭게 구현해봤다.

 

Email 에 인증번호 발송할 이메일 쓰고 전송 버튼 누르면 해당 이메일로 인증 번호가 가는 구조이다. 

구현방법

<form id="registerForm">
    <div>
        <label for="email">Email:</label>
        <input type="email" id="email" name="email" required>
        <button type="button" id="sendVerificationCode">인증번호 전송</button>
    </div>

    <div id="verificationCodeSection" style="display: none;">
        <label for="verification_code">인증번호 입력:</label>
        <input type="text" id="verification_code" name="verification_code" required>
        <button type="button" id="verifyCodeButton">인증번호 확인</button>
    </div>

    <span id="verificationMessage" style="display: none;"></span>
</form>

html 코드 

resources\views\emails\verify.blade.php에 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Email Verification</title>
</head>
<body>
    <p>Your verification code is: <strong>{{ $code }}</strong></p>
</body>
</html>

코드 작성

 

public\js\verification.js에 

document.getElementById('sendVerificationCode').addEventListener('click', function() {
    const email = document.getElementById('email').value;

    if (!email) {
        alert('이메일을 입력하세요.');
        return;
    }

    fetch('/send-verification-code', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
        },
        body: JSON.stringify({ email: email })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert('인증번호가 이메일로 전송되었습니다.');
            document.getElementById('verificationCodeSection').style.display = 'block';
        } else {
            alert('인증번호 전송에 실패했습니다.');
        }
    });
});

document.getElementById('verifyCodeButton').addEventListener('click', function() {
    const email = document.getElementById('email').value;
    const verification_code = document.getElementById('verification_code').value;

    if (!verification_code) {
        alert('인증번호를 입력하세요.');
        return;
    }

    fetch('/verify-code', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
        },
        body: JSON.stringify({ email: email, verification_code: verification_code })
    })
    .then(response => response.json())
    .then(data => {
        var message = document.getElementById('verificationMessage');
        if (data.success) {
            message.textContent = '인증되었습니다.';
            message.style.display = 'block';
            message.style.color = 'green';
        } else {
            message.textContent = '인증번호가 올바르지 않습니다.';
            message.style.display = 'block';
            message.style.color = 'red';
        }
    });
});

 

web.php에

Route::post('/send-verification-code', [UserRegistrationController::class, 'sendVerificationCode']);
Route::post('/verify-code', [UserRegistrationController::class, 'verifyCode']);
Route 작성

app\Http\Controllers\UserRegistrationController.php 에 

 

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;
use Illuminate\Support\Facades\Mail;

class UserRegistrationController extends Controller
{
    // 회원가입 요청을 처리하는 메서드
      // 이메일로 인증번호 전송
    public function sendVerificationCode(Request $request)
    {
        // 이메일 유효성 검사
        $request->validate([
            'email' => 'required|email',
        ]);

        // 이메일 주소 가져오기
        $email = $request->email;

        // 인증 번호 생성 (6자리 랜덤 숫자)
        $verificationCode = rand(100000, 999999);

        // 인증번호를 세션에 저장 (데이터베이스를 사용할 수도 있음)
        session(['verification_code' => $verificationCode, 'verification_email' => $email]);

        // 이메일로 인증 번호 전송
        try {
            Mail::send('emails.verify', ['code' => $verificationCode], function ($message) use ($email) {
                $message->to($email);
                $message->subject('Your Email Verification Code');
            });
        } catch (\Exception $e) {
            return response()->json(['success' => false, 'message' => 'Failed to send verification email.'], 500);
        }

        // 성공적으로 전송되었다는 응답 반환
        return response()->json(['success' => true, 'message' => 'Verification code sent to your email.']);
    }

    // 이메일 인증 번호 확인하는 메서드
    public function verifyCode(Request $request)
    {
    // 이메일 및 인증번호 유효성 검사
    $request->validate([
        'email' => 'required|email',
        'verification_code' => 'required|numeric',
    ]);

    // 세션에서 저장된 인증번호 및 이메일 가져오기
    $storedCode = session('verification_code');
    $storedEmail = session('verification_email');

    // 사용자가 입력한 이메일 및 인증번호가 세션에 저장된 값과 일치하는지 확인
    if ($request->email == $storedEmail && $request->verification_code == $storedCode) {
        // 인증 성공 처리 (필요한 경우 사용자 상태 업데이트 등)
       
        // 인증이 완료되면 세션에서 인증번호 제거
        session()->forget(['verification_code', 'verification_email']);
       
            return response()->json(['success' => true, 'message' => 'Email verified successfully']);
        } else {
            return response()->json(['success' => false, 'message' => 'Invalid verification code or email'], 400);
        }
    }
}

작성 DB에 저장하기 보다 session 에 저장하는 방식으로 진행

 

모르는 부분이나 추가질문사항은 댓글로 남겨주세요.