Improve Security (2) - reCAPTCHA V2 for AppGini

The recommended method of customizing your AppGini-generated application is through hooks. But sometimes you might need to add functionality not accessible through hooks. You can discuss this here.
Post Reply
sathukorala
AppGini Super Hero
AppGini Super Hero
Posts: 121
Joined: 2020-02-16 16:29

Improve Security (2) - reCAPTCHA V2 for AppGini

Post by sathukorala » 2020-05-10 08:38

In this, I will show you how to implement reCAPTCHA V2 for AppGini which will give you a following like login form


14.png
14.png (28.56 KiB) Viewed 3096 times


The steps to do so are the following:

1. Get the reCAPTCHA keys from the Google reCAPTCHA from https://www.google.com/recaptcha
Do not forget to get V2 keys by selecting options like below. Do not forget to add Domains to it (E.g. If you are testing on localhost add localhost to it)

12.png
12.png (15.67 KiB) Viewed 3096 times
13.png
13.png (25.16 KiB) Viewed 3096 times


2. Add below script in header.php file just below <head> tag

Code: Select all

<script src="https://www.google.com/recaptcha/api.js" async defer></script>
3. Replace function logInMember() in incCommon.php and add the following code. Add YOUR-SECRET-KEY to it

Code: Select all

function logInMember(){
		$redir = 'index.php';
		if($_POST['signIn'] != ''){
			if(isset($_POST['signIn']) && !empty($_POST['signIn'])){
				if(isset($_POST['g-recaptcha-response']) && !empty($_POST['g-recaptcha-response'])){
				//your site secret key
				$secret = 'YOUR-SECRET-KEY';
				//get verify response data
				$verifyResponse = file_get_contents('https://www.google.com/recaptcha/api/siteverify?secret='.$secret.'&response='.$_POST['g-recaptcha-response']);
				$responseData = json_decode($verifyResponse);
					if($responseData->success == true){

						if($_POST['username'] != '' && $_POST['password'] != '') {
							$username = makeSafe(strtolower($_POST['username']));
							$hash = sqlValue("select passMD5 from membership_users where lcase(memberID)='{$username}' and isApproved=1 and isBanned=0");
							$password = $_POST['password'];

							if(password_match($password, $hash)) {
								$_SESSION['memberID'] = $username;
								$_SESSION['memberGroupID'] = sqlValue("SELECT `groupID` FROM `membership_users` WHERE LCASE(`memberID`)='{$username}'");

									if($_POST['rememberMe'] == 1) {
										RememberMe::login($username);
									}else{
										RememberMe::delete();
										}
										
									// harden user's password hash
									password_harden($username, $password, $hash);

									// hook: login_ok
									if(function_exists('login_ok')) {
										$args=array();
											if(!$redir=login_ok(getMemberInfo(), $args)) {
												$redir='index.php';
											}
									}	
								redirect($redir);
								exit;
							}
						}
						
						// hook: login_failed
						if(function_exists('login_failed')) {
						$args=array();
						login_failed(array(
						'username' => $_POST['username'],
						'password' => $_POST['password'],
						'IP' => $_SERVER['REMOTE_ADDR']
						), $args);
						}

						if(!headers_sent()) header('HTTP/1.0 403 Forbidden');
						redirect("index.php?loginFailed=1");
						exit;
						
					}
					
				} else {
					$_SESSION['custom_err_msg']= "Please click on reCAPTCHA to login";
					if(!headers_sent()) header('HTTP/1.0 403 Forbidden');
					redirect("index.php?loginFailed=1");
					exit;
					}
			}		
		}		
		// do we have a JWT auth header? 
			jwt_check_login();

			if(!empty($_SESSION['memberID']) && !empty($_SESSION['memberGroupID'])) return;

			// check if a rememberMe cookie exists and sign in user if so 
			if(RememberMe::check()) {
			$username = makeSafe(strtolower(RememberMe::user()));
			$_SESSION['memberID'] = $username;
			$_SESSION['memberGroupID'] = sqlValue("SELECT `groupID` FROM `membership_users` WHERE LCASE(`memberID`)='{$username}'");
			}
	}
	
4. Add the following division just above signIn button <div class="row"> in login.php file. Add YOUR-SITE-KEY to it

Code: Select all

<div class="row" align="center">					
	<div class="g-recaptcha" data-sitekey="YOUR-SITE-KEY"></div>
	<br/>						
</div>
5. Add the following code to hooks > header-extras.php file if not already added for another purpose

Code: Select all

<?php	
if (isset($_SESSION['custom_err_msg'])) {
	$customError ='<div id="customErrorMessage" class="custmErrMsg alert alert-dismissable alert-danger">'.$_SESSION['custom_err_msg'].'</div>';
	echo $customError;			
	if ($_SESSION['custom_err_shown'] == 1){
		unset($_SESSION['custom_err_msg']);
		$_SESSION['custom_err_shown'] = 0;
	} 
	else {
		$_SESSION['custom_err_shown'] = 1;
	}				
}
?>
That's all. Now you can get extra security through google reCAPTCHA V2.

****If you want the reCAPTCHA v3 then please visit the following thread (published by: mghielmi)
viewtopic.php?f=8&t=3284

****Improve Security (1) - Session Control for AppGini can be done as given in the following thread
viewtopic.php?f=4&t=3632

Post Reply