Bài viết trước mình cũng đã có hướng dẫn Tích hợp Google reCAPTCHA v2 vào CodeIgniter4, trong bài viết tiếp theo này mình sẽ hướng dẫn các bạn tích hợp nốt Google reCAPTCHA v3 vào CodeIgniter4 nữa. Bạn nào chưa đọc bài viết trước liên quan đến chuỗi chủ đề reCaptcha thì đọc lại bài viết đó nhé.
Nọi dung Google reCaptcha là gì và có bai nhiêu loại Google reCaptcha thì vui lòng đọc bài kia (đã dẫn link ở trên), bài viết này sẽ không dài dòng và sẽ tập trung vào việc tích hợp Google reCaptcha vào thôi nhé.
Phụ mục
Đăng ký API Google reCaptcha
Tương tự như cách đăng ký reCaptcha V2, để đăng ký reCaptcha V3 bạn vẫn có thể thực hiện bằng một vài thao tác đơn giản mà thôi. Cụ thể như 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.
- Chọn Google reCaptcha V3.
- Ấ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 v3 vào CodeIgniter4
Về cơ bản, cách thích hợp reCaptcha V3 cũng chẳng khác gì tích hợp Google reCAPTCHA v2 cả. Tuy nhiên, vì Google reCaptcha V3 hoạt động dưới nền nên phần trình bày ngoài giao diện người dùng cũng có 1 vài sự thay đổi.
Nếu bạn nào đã đọc vài viết tích hợp Google reCAPTCHA v2 thì sẽ thấy đa phần nội dung cũng sẽ tương tự như V2 mà thôi.
1. Tạo variables lưu trữ SITE KEY và SECRET KEY trên .env
Lưu trữ những chuỗi Site Key và Secrect Key, nơi nào phù hợp hơn file .env
Chúng ta trữ lại như sau:
reCAPTCHA.v3.SITE_KEY = 'xxxxxxxxxx' reCAPTCHA.v3.SECRET_KEY = 'xxxxxxxxxxxx' |
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 26 | <?php namespace Config; class CaptchaValidation{ public function verifyrecaptchaV3(string $str, ?string &$error = null): bool { $secretkey = getenv('reCAPTCHA.v3.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); $score = 0.6; // 0 - 1 if($responseData->success && $responseData->score > $score) { // Verified return true; } } $error = "Invalid captacha"; return false; } } |
Cách xác thực của V3 có khác một chút so với V2 là ở phiên bản này reCaptcha sẽ đánh giá mức độ thông qua điểm $score
. Giá trị sẽ từ 0 -> 1. Càng về 0 nghĩa lầ Google reCaptcha cho rằng dữ liệu càng giống Bot và ngược lại càng gần với 1 thì Google đánh giá xác thực này đáng tín.
Vậy lám sao Google có thể xác định được ??? Theo những gì mình tìm hiểu được là Google reCaptcha V3 ứng dụng nhiều thông itn mà Google thu thập được; trong đó một trong những yếu tố quan trọng giúp Google xác định được “Human” hay “Bot” là việc nó theo dõi việc di chuyển con trỏ chuột. Cụ thể mình sẽ viết trong một vài viết khác.
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:
<?php namespace Config; use CodeIgniter\Config\BaseConfig; use CodeIgniter\Validation\CreditCardRules; use CodeIgniter\Validation\FileRules; use CodeIgniter\Validation\FormatRules; use CodeIgniter\Validation\Rules; use Config\CaptchaValidation; // Custom reCAPTCHA v3 validation class Validation extends BaseConfig { // -------------------------------------------------------------------- // Setup // -------------------------------------------------------------------- /** * Stores the classes that contain the * rules that are available. * * @var string[] */ public $ruleSets = [ Rules::class, FormatRules::class, FileRules::class, CreditCardRules::class, CaptchaValidation::class, // Custom reCAPTCHA v3 validation ]; /** * Specifies the views that are used to display the * errors. * * @var array<string, string> */ public $templates = [ 'list' => 'CodeIgniter\Validation\Views\list', 'single' => 'CodeIgniter\Validation\Views\single', ]; // -------------------------------------------------------------------- // Rules // -------------------------------------------------------------------- } |
3. Tạo View
Khác với V2, reCaptcha V3 không cần người dùng thực hiện bất kỳ thao tác nào nên nó cũng ít ảnh hưởng đến layout chung của website. Đây là những việc cụ thể mà bạn cần làm nếu sử dụng V3
- 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
- Tạo script cho sự kiện onSubmit để kiểm tra dữ liệu
Đọc code cho nhanh và đỡ dài dòng nhé:
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 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?render=<?= getenv('reCAPTCHA.v3.SITE_KEY') ?>"></script> <!-- Include script --> <script type="text/javascript"> function onSubmit(e) { e.preventDefault(); grecaptcha.ready(function() { grecaptcha.execute("<?= getenv('reCAPTCHA.v3.SITE_KEY') ?>", {action: 'submit'}).then(function(token) { // Store recaptcha response document.getElementById("recaptcha_response").value = token; // Submit form document.getElementById("contactForm").submit(); }); }); } </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 id="contactForm" method="post" action="<?=site_url('page/submitContactUs')?>" onSubmit="onSubmit(event)"> <?= csrf_field(); ?> <!-- Recaptcha Error --> <?php if( $validation->getError('recaptcha_response') ) {?> <div class="alert alert-danger"> <?= $validation->getError('recaptcha_response'); ?> </div> <?php }?> <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 "> <div class="col-sm-offset-2 col-sm-10"> <input type="hidden" id="recaptcha_response" name="recaptcha_response" value=""> <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', 'recaptcha_response' => 'required|verifyrecaptchaV3', ],[ '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', 'Request Submitted Successfully!'); session()->setFlashdata('alert-class', 'alert-success'); } return redirect()->route('/'); } } |
Vậy là xong ! Cảm ơn bạn makitweb đã viết code cho mình copy cho lẹ :D