Last active
May 21, 2019 14:01
-
-
Save nikoz84/ee10ff9a024273d179c3e78d99f1f994 to your computer and use it in GitHub Desktop.
VALIDATOR RULE FOR GOOGLE RECAPTCHA IN LARAVEL AND COMPONENT VUEJS RENDER RECAPTCHA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<div class="conteiner"> | |
<div class="row col-md-7"> | |
<form v-on:submit.prevent="send()" v-if="!isSend"> | |
<div class="form-group" v-bind:class="{ 'has-error': errors.name && errors.name.length > 0 }"> | |
<label for="nome">Nome:<span class="glyphicon-asterisk"></span></label> | |
<input type="text" class="form-control" id="nome" v-model="name" placeholder="Digite seu nome"> | |
<small class="text-danger" | |
v-if="errors.name" | |
v-for="(error,i) in errors.name" | |
v-bind:key="i" | |
v-text="error"> | |
</small> | |
</div> | |
<div class="form-group" v-bind:class="{ 'has-error': errors.email && errors.email.length > 0 }"> | |
<label for="email">E-mail:<span class="glyphicon-asterisk"></span></label> | |
<input type="email" | |
class="form-control" | |
id="email" | |
v-model="email" | |
placeholder="Digite seu e-mail" | |
autocomplete="off"> | |
<small class="text-danger" | |
v-if="errors.email" | |
v-for="(error,i) in errors.email" | |
v-bind:key="i" | |
v-text="error"> | |
</small> | |
</div> | |
<div class="form-group" v-bind:class="{ 'has-error': errors.subject && errors.subject.length > 0 }"> | |
<label for="assunto">Assunto:<span class="glyphicon-asterisk"></span></label> | |
<input type="text" class="form-control" id="assunto" v-model="subject" placeholder="Qual é o assunto do contato"> | |
<small class="text-danger" | |
v-if="errors.subject" | |
v-for="(error,i) in errors.subject" | |
v-bind:key="i" | |
v-text="error"> | |
</small> | |
</div> | |
<div class="form-group" v-bind:class="{ 'has-error': errors.message && errors.message.length > 0 }"> | |
<label for="mensagem">Mensagem:<span class="glyphicon-asterisk"></span></label> | |
<textarea class="form-control" id="mensagem" v-model="message" placeholder="Digite aqui sua mensagem"></textarea> | |
<small class="text-danger" | |
v-if="errors.message" | |
v-for="(error,i) in errors.message" | |
v-bind:key="i" | |
v-text="error"> | |
</small> | |
</div> | |
<div class="form-group" v-bind:class="{ 'has-error': errors.recaptcha && errors.recaptcha.length > 0 }"> | |
<label for="mensagem">Código de segurança:<span class="glyphicon-asterisk"></span></label> | |
<div class="form-group row"> | |
<div class="col-md-6 offset-md-4"> | |
<div class="g-recaptcha" :data-sitekey="siteKey"></div> | |
<small class="text-danger" | |
v-if="errors.recaptcha" | |
v-for="(error,i) in errors.recaptcha" | |
v-bind:key="i" | |
v-text="error"> | |
</small> | |
</div> | |
</div> | |
</div> | |
<div class="form-group"> | |
<button class="btn btn-default" v-if="!isLoading">Enviar</button> | |
</div> | |
</form> | |
<div v-else-if="isSend"> | |
Denúncia enviada com sucesso!! | |
</div> | |
<div class="col-md-12" v-if="isLoading"> | |
<div class="col-md-1"><Loader></Loader></div> | |
<div class="col-md-4">enviando denúncia...</div> | |
</div> | |
</div> | |
</div> | |
</template> | |
<script> | |
import Loader from "../components/LoaderComponent.vue"; | |
import client from "axios"; | |
export default { | |
name: "DenunciaForm", | |
components: { Loader }, | |
data() { | |
return { | |
name: "", | |
email: "", | |
subject: "", | |
message: "", | |
isSend: false, | |
isLoading: false, | |
r_id: 0, | |
siteKey: "YOUR PUBLIC KEY", // HERE YOUR PUBLIC KEY | |
isError: true, | |
success: false, | |
errors: { | |
name: [], | |
email: [], | |
subject: [], | |
message: [], | |
recaptcha: [] | |
} | |
}; | |
}, | |
mounted() { | |
if (window.grecaptcha) { | |
// RENDER THE RECAPTCHA | |
let container = document.getElementsByClassName("g-recaptcha")[0]; | |
if (typeof grecaptcha.render === "function") { | |
this.r_id = grecaptcha.render(container, { | |
sitekey: this.siteKey | |
}); | |
} | |
} | |
}, | |
methods: { | |
async send() { | |
this.isLoading = true; | |
let resRecaptcha = grecaptcha.getResponse(); | |
let data = { | |
name: this.name, | |
email: this.email, | |
subject: this.subject, | |
message: this.message, | |
recaptcha: resRecaptcha | |
}; | |
let resp = await axios.post("/your-api-end-point", data); // HERE YOUR API END POINT | |
this.isSend = resp.data.success; | |
if (resp.data.success) { | |
this.isLoading = false; | |
} else { | |
this.isLoading = false; | |
this.isError = resp.data.success; | |
if (resp.data.errors) { | |
this.errors = resp.data.errors; | |
} | |
} | |
setTimeout(() => { | |
this.isError = true; | |
}, 3000); | |
} | |
} | |
}; | |
</script> | |
<style lang="scss" scoped> | |
form { | |
margin-top: 30px; | |
margin-bottom: 30px; | |
} | |
textarea { | |
height: 170px; | |
resize: none; | |
} | |
</style> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// VALIDATOR RULE FOR GOOGLE RECAPTCHA IN THE VALIDATOR LARAVEL | |
<?php | |
namespace App\Helpers; | |
use Illuminate\Contracts\Validation\Rule; | |
use App\Helpers\GoogleRecaptcha; | |
class GoogleRecaptchaValidator implements Rule | |
{ | |
public function passes($attribute, $value) | |
{ | |
$recaptcha = new GoogleRecaptcha($value); | |
return $recaptcha->validate(); | |
} | |
public function message() | |
{ | |
return 'código de segurança não válido'; | |
} | |
} | |
// CLASS THAT CONTAIN THE CALL INTO GOOGLE API | |
<?php | |
namespace App\Helpers; | |
class GoogleRecaptcha | |
{ | |
private $recaptcha; | |
public function __construct($recaptcha) | |
{ | |
$this->recaptcha = $recaptcha; | |
} | |
/** | |
* Validaçao codigo de segurança do recaptcha do Google | |
* @param $response String cadeia de carecteres | |
* @return array uma resposta em formato json | |
*/ | |
public function validate() | |
{ | |
$success = false; | |
// HERE YOU NEED TO ADD YOUR RECAPTCHA SECRET OR CONFIG IN YOUR .ENV FILE env('GOOGLE_RECAPTCHA_PRIVATE') | |
// OR FROM YOUR CONFIG FILE | |
$secret = config('recaptcha.PRIVATE_KEY'); | |
$url = "https://www.google.com/recaptcha/api/siteverify"; | |
$data = [ | |
'secret' => $secret, | |
'response' => $this->recaptcha | |
]; | |
$dataQuery = http_build_query($data); | |
$length = strlen($dataQuery); | |
$options = [ | |
'http' => [ | |
'method' => 'POST', | |
'header' => "Content-Type: application/x-www-form-urlencoded\r\n" . | |
"Content-Length: {$length}", | |
'content' => $dataQuery | |
] | |
]; | |
$context = stream_context_create($options); | |
$response = file_get_contents($url, false, $context); | |
$responseDecode = json_decode($response); | |
if ($responseDecode->success) { | |
$success = true; | |
} | |
return $success; | |
} | |
} | |
// IN YOUR CONTROLLER CALL DE TRAIT ApiResponser OR YOU CAN CREATE A CONTROLLER ApiController | |
// THAT EXTENDS FROM BASE CONTROLLER AND THE OTHERS CONTROLLERS EXTENDS FROM ApiController | |
// AND YOU CAN USE THE METHODS OF THE TRAIT $this->errorResponse $this->showOne $this->successResponse | |
use ApiResponser; | |
public function create() | |
{ | |
// CREATE A RULES FILE IN YOUR CONFIG FOLDER AND YOU CAN USE THE METHOD config('rules.your-form') | |
$validator = Validator::make($this->request->all(), config('rules.denuncia')); | |
if ($validator->fails()) { | |
// I CREATE A TRAIT TO RESPONSE JSON DATA | |
return $this->errorResponse($validator->errors(), 'Não foi possível registrar a denúncia', 403); | |
} | |
} | |
// IF YOU CREATE A CONFIG FILE | |
<?php | |
return [ | |
'denuncia' => [ | |
'name' => 'required|min:5', | |
'email' => 'required', | |
'url' => 'required', | |
'subject' => 'required', | |
'message' => 'required', | |
'recaptcha' => ['required', new \App\Helpers\GoogleRecaptchaValidator], | |
], | |
'other-form' => [ | |
'field' => 'nullable', | |
'field2' => 'required', | |
] | |
]; | |
// TRAIT FOR RESPONSES | |
<?php | |
namespace App\Traits; | |
use Illuminate\Support\Collection; | |
use Illuminate\Database\Eloquent\Model; | |
use Illuminate\Pagination\LengthAwarePaginator as Paginator; | |
trait ApiResponser | |
{ | |
protected function successResponse($data, $message, $code) | |
{ | |
return response()->json([ | |
'metadata' => $data, | |
'message' => $message, | |
'success' => true | |
], $code); | |
} | |
protected function errorResponse($errors, $message, $code) | |
{ | |
return response()->json([ | |
'errors'=> $errors, | |
'message' => $message, | |
'success' => false | |
], $code); | |
} | |
protected function showAll(Collection $collection, $message = '', $code = 200) | |
{ | |
return $this->successResponse($collection, $message, $code); | |
} | |
protected function showAsPaginator(Paginator $paginator, $message = '', $code = 200) | |
{ | |
return response()->json([ | |
'paginator' => $paginator, | |
'message' => $message, | |
'success' => true | |
], $code); | |
} | |
protected function showOne(Model $instance, $message = '', $code = 200) | |
{ | |
return $this->successResponse($instance, $message, $code); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment