Holly shit ! Mình vừa mới mất 3h đồng hồ trong cuộc đời để ngồi tích hợp ngược reCAPTCHA V2 vào Form contact trong CodeIgniter 4 và bây giờ ngồi chia sẻ kinh nghiệm cho các bạn. Vốn dĩ trước đây mình dùng reCAPTCHA V3 tuy nhiên sau một vài phiền toái không đáng có, mình quyết định quay lại với reCAPTCHA V2. Cụ thể như thế nào mình sẽ có một bài so sánh sau. Bài này là vế vấn đề kỹ thuật.
Nói một cách ngắn gọn thì Google reCaptcha nó giống như một người bảo vệ website của bạn trước mấy đứa spam (và mấy con bot spam). Thông thường, chúng ta thường dùng chúng để ngăn ngừa một ai đó phá hỏng hoặc làm cho website của bạn trở nên hỗn loạn. Chúng thường được đặt vào các contact form, register form hoặc bình luận trên trang web.
Có 2 loại Google reCaptcha
- Bạn phải thực hiện 1 thử thách (thường là lựa chọn ảnh) để công cụ xác định bạn là người thật (Google reCaptcha – V2).
- Bạn không cần làm gì cả, Google reCaptcha V3 sẽ hoạt động ở chế độ nền và làm mọi thứ cần thiết(Google reCaptcha – V3).
Trong bài này dĩ nhiên là chúng ta sẽ hướng đến Google reCaptcha V2 nhé !
Phụ mục
Đăng ký API Google reCaptcha
Tính ra thì việc đăng ký này khá đơn giản với dân Dev. Bạn chỉ việc vào trang Google reCaptcha cà đăng ký một API để sử dụng. Mình sẽ tóm gọn trong mấy bước sau:
- Truy cập vào liên kết Google reCaptcha này.
- Điền đầy đủ thông tin theo các bước hướng dẫn.
- Nhớ là chọn reCaptcha V2 thôi.
- Ấn Submit
Sau đó tiến hành lấy API SITE KEY và SECRET kKEY về xài thôi.
Sau khi có Key giờ là lúc tiến hành lập trình trên CodeIgniter. Let;s go !!
Tích hợp Google reCAPTCHA v2 vào CodeIgniter4
1. Tạo variables lưu trữ SITE KEY và SECRET KEY trên .env
Đầu tiên chúng ta cần một nơi lưu trữ những chuỗi Site Key và Secrect Key đã. Không nơi nào phù hợp hơn file .env (hoặc bạn có thể lưu trong /app/Config/App.php nếu muốn).
Chúng ta trữ lại như sau:
1 2 3 | reCAPTCHA.v2.SITE_KEY = 'xxxxxxxxxx' reCAPTCHA.v2.SECRET_KEY = 'xxxxxxxxxxxx' reCAPTCHA.v2.URL="https://www.google.com/recaptcha/api/siteverify" |
Để tiện cho việc sử dụng sau này, mình lưu trữ thêm URL. Bạn thích thì lưu không thì gọi chỗ nào cũng được.
2. Bổ sung phương thức Validate
Tạo một file CaptchaValidation.php
tại thư mục app/Config File này bạn xây. dựng phương thức xác thực cho reCaptcha. Nội dung của nó như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <?php namespace Config; class CaptchaValidation{ public function verifyrecaptcha(string $str, ?string &$error = null): bool { $secretkey = getenv('reCAPTCHA.v2.SECRET_KEY'); if(($str) && !empty($str)) { $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=".$secretkey."&response=".$str."&remoteip=".$_SERVER['REMOTE_ADDR']); $responseData = json_decode($response); if($responseData->success) { // Verified return true; } } $error = "Invalid captacha"; return false; } } |
Tiếp theo, chúng ta bổ sung phương thức verifyrecaptcha đã tạo trong class CaptchaValidation ở trên vào Validation của CodeIgniter4.
Bạn mở file app/Config/Validation.php và thực hiện một số tinh chỉnh như sau:
- Mở file
app/Config/Validation.php
file. - Include class
Config\CaptchaValidation
vào - Chỉ định
CaptchaValidation::class
vào mảng$ruleSet
Dưới đây là code hoàn chỉnh mà bạn có thể tham khảo và chỉnh theo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | <?php namespace Config; use CodeIgniter\Config\BaseConfig; use CodeIgniter\Validation\StrictRules\CreditCardRules; use CodeIgniter\Validation\StrictRules\FileRules; use CodeIgniter\Validation\StrictRules\FormatRules; use CodeIgniter\Validation\StrictRules\Rules; use Config\CaptchaValidation; // Custom reCAPTCHA validation class Validation extends BaseConfig { // -------------------------------------------------------------------- // Setup // -------------------------------------------------------------------- /** * Stores the classes that contain the * rules that are available. * * @var string[] */ public array $ruleSets = [ Rules::class, FormatRules::class, FileRules::class, CreditCardRules::class, CaptchaValidation::class, // Custom reCAPTCHA validation ]; /** * Specifies the views that are used to display the * errors. * * @var array<string, string> */ public array $templates = [ 'list' => 'CodeIgniter\Validation\Views\list', 'single' => 'CodeIgniter\Validation\Views\single', ]; // -------------------------------------------------------------------- // Rules // -------------------------------------------------------------------- } |
3. Tạo View
Đã có phương thức Validation dữ liệu, giờ chúng ta tạo View để xây dựng giao diện gửi tin và valid dữ liệu sử dụng kèm với đó là Captcha V2. Ở phần valid các dữ liệu cơ bản mình sẽ không hướng dẫn. Chúng ta chỉ tập trung vào việc xây dựng phương thức xác thực cho Captcha V2. Công việc cụ thể như sau:
- Tạo file
contact.php
trong View để chứa View của tính năng này. - Chèn
api.js
từ Google vào để kết nối API - Tạo contact form với các dữ liệu bình thường
- Bổ sung reCaptcha V2 để xác thực:
Để nhanh chóng thực hiện, bạn có thể tham khảo đoạn code sau mình làm sẵn:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Add Google reCAPTCHA v2 to form in CodeIgniter 4</title> <!-- Bootstrap CSS --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" > <!-- reCAPTCHA JS--> <script src='https://www.google.com/recaptcha/api.js'></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-6 mt-5" style="margin: 0 auto;"> <?php // Display Response if(session()->has('message')){ ?> <div class="alert <?= session()->getFlashdata('alert-class') ?>"> <?= session()->getFlashdata('message') ?> </div> <?php } ?> <h2 class="mb-4">Contact US</h2> <?php $validation = \Config\Services::validation(); ?> <form method="post" action="<?=site_url('page/submitcontactus')?>"> <?= csrf_field(); ?> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="name">Name:</label> <div class="col-sm-10"> <input type="text" class="form-control" id="name" placeholder="Enter Name" name="name" value="<?= old('name') ?>"> </div> <!-- Error --> <?php if( $validation->getError('name') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('name'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="email">Email:</label> <div class="col-sm-10"> <input type="email" class="form-control" id="email" placeholder="Enter Email" name="email" value="<?= old('email') ?>"> </div> <!-- Error --> <?php if( $validation->getError('email') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('email'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="subject">Subject:</label> <div class="col-sm-10"> <input type="text" class="form-control" id="subject" placeholder="Enter Subject" name="subject" value="<?= old('subject') ?>" > </div> <!-- Error --> <?php if( $validation->getError('subject') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('subject'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <label class="control-label col-sm-2" for="message">Message:</label> <div class="col-sm-10"> <textarea class="form-control" id="message" name="message"><?= old('message') ?></textarea> </div> <!-- Error --> <?php if( $validation->getError('message') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('message'); ?> </div> <?php }?> </div> <div class="form-group mb-4"> <!-- reCAPTCHA --> <div class="g-recaptcha" data-sitekey="<?= getenv('reCAPTCHA.v2.SITE_KEY ') ?>" ></div> <!-- Error --> <?php if( $validation->getError('g-recaptcha-response') ) {?> <div class='text-danger mt-2'> * <?= $validation->getError('g-recaptcha-response'); ?> </div> <?php }?> </div> <div class="form-group "> <div class="col-sm-offset-2 col-sm-10"> <button type="submit" class="btn btn-info">Submit</button> </div> </div> </form> </div> </div> </div> </body> </html> |
4.Tạo Controller và Validate reCAPTCHA
Bạn đã có dữ liệu từ View gửi lên với reCaptcha, giờ bạn cần xử lý dữ liệu và gửi email (hoặc tạo thông tin liên hệ gì đó). Cũng như phần trên, mình cũng sẽ chỉ nói đến những thứ liên quan đến reCaptcha.
- Tạo Controller
- Tạp 2 method chính là
index
(để load form) vàsubmitContact
(để xử lý khi người dùng bấm submit) - Validate dữ liệu đầu vào
- Sử dụng phương thức
verifyrecaptcha
để xác thực reCaptcha - Gửi tin nhắn, email hoặc thông báo sau khi đã validate xong
Đây là code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <?php namespace App\Controllers; use App\Controllers\BaseController; class PagesController extends BaseController{ public function index(){ return view('index'); } public function submitcontactus(){ // Validation $input = $this->validate([ 'name' => 'required', 'email' => 'required', 'subject' => 'required', 'message' => 'required', 'g-recaptcha-response' => 'required|verifyrecaptcha', ],[ 'g-recaptcha-response' => [ 'required' => 'Please verify captcha', ], ]); if (!$input) { // Not valid $data['validation'] = $this->validator; return redirect()->back()->withInput()->with('validation', $this->validator); }else{ // Set Session session()->setFlashdata('message', 'Submitted Successfully!'); session()->setFlashdata('alert-class', 'alert-success'); } return redirect()->route('/'); } } |
Vậy là đã xong. Code mình post đây còn việc đọc hiểu là việc của các bạn.
Đừng bắt giải thích từng dòng nghen.