Skip to content

Instantly share code, notes, and snippets.

@nikoz84
Last active May 21, 2019 14:01
Show Gist options
  • Save nikoz84/ee10ff9a024273d179c3e78d99f1f994 to your computer and use it in GitHub Desktop.
Save nikoz84/ee10ff9a024273d179c3e78d99f1f994 to your computer and use it in GitHub Desktop.
VALIDATOR RULE FOR GOOGLE RECAPTCHA IN LARAVEL AND COMPONENT VUEJS RENDER RECAPTCHA
<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>
// 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