Do not speak Portuguese? Translate this site with Google or Bing Translator
Detecção de spam do Laravel

Posted on: July 10, 2021 12:39 PM

Posted by: Renato

Categories: Laravel PHP webdev web

Views: 466

 

Introdução

Como você já sabe, o Laravel é o framework MVC PHP mais poderoso e mais usado para construir aplicações web completas. Com sua sintaxe expressiva e bonita e conjunto de ferramentas moderno, o Laravel é o líder na indústria. O Laravel foca primeiro no usuário final, o que significa que seu foco está na simplicidade, clareza e execução do trabalho.
Para mais informações sobre o framework Laravel, visite a página de documentação, seguindo este link .
Por todas essas vantagens do framework, estamos usando muito o Laravel, porque tendemos e nossa ideia é seguir todas as últimas tendências da indústria de TI.
Por isso, neste post, usaremos o Laravel 5.6. Você vai aproveitar!

Aplicação de esqueleto

Para o propósito deste tutorial, um aplicativo Laravel foi criado do zero com as seguintes funcionalidades:

  • Funcionalidade de login / registro com o comando core auth ;
  • Criou alguns usuários de teste no banco de dados;
  • Controladores de posts e comentários, modelos, relações e migrações com alguns dados de amostra.

Detecção de Spam

Existe um grande problema com os spammers hoje em dia. Existem muitos scripts em execução em diferentes sites e tentam enviar um formulário onde quer que eles surjam. Você já se perguntou por quê? Se você tem um pouco de experiência com SEO, pode entender que o motivo é muito simples.
Eles tentam adicionar um link (backlink de spam) que redireciona para sites de spammers em potencial. Com isso, eles constroem autoridade em seus sites e é mais fácil classificar o site em uma posição superior na pesquisa do Google quando alguém busca por palavras-chave relacionadas ao conteúdo de seus sites. A classificação mais elevada na pesquisa do Google é calculada principalmente com base nos backlinks e na autoridade dos sites. A autoridade do site é aumentada com mais backlinks.
Este é o principal motivo pelo qual precisamos ter cuidado com spammers em nosso aplicativo, porque podemos facilmente encontrar nossos aplicativos com muitos comentários de spam que não estarão relacionados com o conteúdo do site.

Regras de spam que serão usadas

Neste tutorial, comentários de spam em postagens de blog serão detectados. Claro, existem muitas regras que podem ser apresentadas, mas por enquanto, a atenção estará em 3 regras. Esses são:

1. Palavras-chave inválidas

Este será um conjunto de palavras ou frases. Cada comentário que contiver qualquer uma dessas palavras ou frases será marcado como spam.

2. Tecla mantida pressionada

Imagine que alguém, visite seu site e apenas por diversão mantenha pressionada uma tecla e tente postar um comentário. Por exemplo: 'aaaaaaaa', 'bbbbbbbbb', etc. Devemos prevenir este tipo de ação e marcar esses comentários como spam.

3. Comentários postados com muita frequência

Devemos evitar que os usuários postem comentários com muita frequência. Haverá um parâmetro de configuração com um número inteiro que nos dirá quanto tempo o usuário deve esperar antes de postar um novo comentário.

Vamos codificar!

Com certeza, para não incomodá-lo com muitas informações desnecessárias sobre a aplicação que foi configurada para este tutorial, o foco será apenas compartilhar trechos de código com boa explicação, que sejam mais úteis e compreensíveis.
Nesta seção, mostraremos um post com o fluxo básico que é habilitado com o lindo componente HTTP Foundation que o Laravel usa.
Rota no arquivo web.php:

 

 
 
 
 
 



<?php

Route::get('/blog/{slug}', 'PostsController@show');

?>

 

Método em PostsController:

 

 
 
 
 
 



<?php

/**

* Show single post

*

* @param string $slug

* @return \Illuminate\Http\Response

*/

public function show($slug)

{

$post = Post::where(‘slug’, $slug)->first();

return view('blog.single_post', compact('post'));

}

?>


Explicação do código:

 

  • Encontre a postagem com o slug (é um campo vunique no banco de dados);
  • Retorne a vista com parâmetro do post.

Depois disso, a visualização será renderizada em um modelo de lâmina com os dados da postagem.
Na visualização, há um formulário para adicionar um comentário à postagem.
É assim na vida real:

Um formulário para adicionar um comentário à postagem

E o formulário no modelo de lâmina (usando bootstrap 4):

 

 
 
 
 
 



<form action="/blog/{{$post->id}}/store-comment" method="POST">

{{ csrf_field() }}

<div class="form-group">

<textarea class="form-control" name="body" rows="3"></textarea>

</div>

<button class="btn btn-primary" type="submit">

Submit

</button>

</form>

 

Ao enviar, a ação do formulário é configurada para postar a solicitação para a rota fornecida. O método post é tratado assim no arquivo web.php:

 

 
 
 
 
 



<?php

Route::post('/blog/{post}/store-comment', 'CommentsController@store');

?>


E o método em CommentsController:

 

 

 
 
 
 
 



<?php

/**

* Store new post

*

* @param App\Post $post

* @return Illuminate\Http\RedirectResponse

*/

public function store(Post $post)

{

try {

resolve(Spam::class)->detect(request('body'));



$post = Post::find($post->id);



$post->comments()->create([

'user_id' => auth()->id(),

'body' => request('body'),

]);



return redirect("/blog/{$post->url}#comments")->with([

'status' => 'success',

'message' => 'Your comment was published successfully',

]);

} catch (Exception $e) {

return redirect("/blog/{$post->url}#comments")->with([

'status' => 'danger',

'message' => $e->getMessage(),

]);

}

}

?>

 

 

Explicação do código acima:

  • Encontrar a postagem por ID na qual o usuário deseja comentar;
  • Criando o comentário (observe a relação);
  • Redirecione para a postagem anterior com um status e uma mensagem.

Espero que até agora tudo esteja claro. Agora vem a parte interessante.
Será criada uma classe de spam dedicada que tratará de tudo relacionado à detecção de comentários de spam. Claro, vamos criá-lo seguindo as melhores práticas e mantendo a regra de separação de interesses.
Vamos criar uma classe Spam genérica:

 

 
 
 



<?php



namespace App\Inspections;



class Spam

{

/**

* All registered inspections

*

* @var array

*/

protected $inspections = [

InvalidKeywords::class,

KeyHeldDown::class,

CommentsPostedVeryOften::class,

];



/**

* Detect spam

*

* @param string $body

* @return bool

*/

public function detect($body)

{

foreach ($this->inspections as $inspection) {

app($inspection)->detect($body);

}



return false;

}

}

 

 Deixe-me explicar o código acima:

  • A classe Spam é criada e colocada na pasta App \ Inspections;
  • Na propriedade $ inspections, em um array são colocadas todas as classes com regras específicas que foram separadas durante a refatoração do código;
  • Abaixo, no método detect (), o corpo do comentário é passado e percorre todas as classes na propriedade $ inspections, passando o nome da classe para o auxiliar app () para resolvê-lo no contêiner e chamando cada detect de classe () método com um parâmetro que é o corpo do comentário (tipo string).

Você pode ver que cada regra de spam é separada em classes diferentes. Todas as classes são colocadas na pasta App \ Inspections.
Então, vamos falar sobre cada aula e explicar o que exatamente elas estão fazendo.

Regra de palavras-chave inválidas

Este é o código para esta aula:

 

 
 
 
 



<?php



namespace App\Inspections;



use Exception;



class InvalidKeywords

{

/**

* All spam keywords

*

* @var array

*/

protected $keywords = [

'customer support',

];



/**

* Detect spam

*

* @param string $body

* @throws \Exception

*/

public function detect($body)

{

foreach ($this->keywords as $keyword) {

if (stripos($body, $keyword) !== false) {

throw new Exception("Your comment contains spam.");

}

}

}



}

 
  • Inicializando uma propriedade $ keywords que é uma matriz de todas as palavras-chave que reconhecemos como spam. Por enquanto, há apenas uma palavra-chave, mas você pode escrever quantas forem necessárias;
  • O método detect () chamado da classe Spam com o parâmetro $ body passado da classe Spam também;
  • Loop através da propriedade $ keywords, e para cada uma das palavras-chave, há uma verificação se a palavra-chave existe no corpo do comentário e, em caso afirmativo, lança uma Exceção.

Simples assim.

Regra de tecla pressionada

Este é o código para esta aula:

 

 
 
 



<?php



namespace App\Inspections;



use Exception;



class KeyHeldDown

{

/**

* Detect spam

*

* @param string $body

* @throws \Exception

*/

public function detect($body)

{

if (preg_match('/(.)\\1{4,}/', $body)) {

throw new Exception("Your comment contains spam.");

}

}

}

 
  • O método detect () chamado da classe Spam com o parâmetro $ body passado da classe Spam também;
  • Verificar com expressão regular se o corpo do comentário contém a mesma letra em uma linha mais de 4 vezes. É 4 vezes para os fins deste exemplo, você pode alterá-lo de acordo com suas necessidades;
  • Se a condição for atendida, lance Exception.

Os comentários postados costumam reger

Este é o código para esta aula:

 

 
 
 



<?php



namespace App\Inspections;



use App\User;

use Carbon\Carbon;

use Exception;



class CommentsPostedVeryOften

{

/**

* Detect spam

*

* @param string $body

* @throws \Exception

*/

public function detect($body)

{

$user = User::find(auth()->id());



$latestComment = $user->getLatestCommentByUser();



if ($latestComment) {

$data = $this->prepareCommonData($latestComment);



if ($user->canUserPostComment($data)) {

throw new Exception("You can post only once in {$data["userCommentFrequency"]} minutes.");

}

}

}



/**

* Prepare common data

*

* @param Collection $latestComment

* @return array

*/

public function prepareCommonData($latestComment)

{

return [

'latestCommentCreated' => new Carbon($latestComment->created_at),

'userCommentFrequency' => config('app.spam_detection.user_can_comment_once_in'),

];

}

}

 
  • O método detect () chamado da classe Spam com o parâmetro $ body passado da classe Spam também;
  • Encontrar o usuário conectado;
  • Obter o comentário mais recente do usuário conectado;
    • O código é separado em um método getLatestCommentByUser () declarado no modelo de usuário:

 

 
 
 



<?php

/**

* getLatestCommentByUser - get latest comment by user

*

*/

public function getLatestCommentByUser()

{

return $this->comments()->latest()->first();

}

?>

 

 

  • Se o usuário tiver comentários, existe uma condição que verifica se o usuário pode postar um novo comentário com outro método canUserPostComment () declarado no modelo do usuário e passou um dado preparado com a data do último comentário criado e um parâmetro de configuração do arquivo app.php que nos informa com que frequência um usuário pode postar um comentário. Por enquanto, é uma vez em 10 minutos.
    • Abaixo está o código do método canUserPostComment ():

 

 
 
 



<?php

/**

* Check if user can post comment

*

* @param string $data

* @return bool

*/

public function canUserPostComment($data)

{

return $data['latestCommentCreated']->diffInMinutes() < $data['userCommentFrequency'];

}

?>

 
  • Se o usuário postar um comentário em menos de 10 minutos, a condição é atendida e o código lança Exceção com uma mensagem adequada.

Existe apenas uma e última etapa antes de concluir este recurso. Para chamar a classe Spam e detectar se o comentário é spam em todas as regras de spam, você deve adicionar mais uma linha de código no método store () do CommentsController. Esta é a linha do código:

 

 
 
 



<?php

resolve(Spam::class)->detect(request('body'));

?>

 

E depois disso, o método store () ficará assim:

 

 
 
 



<?php

/**

* Store new post

*

* @param App\Post $post

* @return Illuminate\Http\RedirectResponse

*/

public function store(Post $post)

{

try {

resolve(Spam::class)->detect(request('body'));



$post = Post::find($post->id);



$post->comments()->create([

'user_id' => auth()->id(),

'body' => request('body'),

]);



return redirect("/blog/{$post->url}#comments")->with([

'status' => 'success',

'message' => 'Your comment was published successfully',

]);

} catch (Exception $e) {

return redirect("/blog/{$post->url}#comments")->with([

'status' => 'danger',

'message' => $e->getMessage(),

]);

}

}

?>


Você sempre tem que preferir uma quantidade menor de código e é por isso que aqui é usado o helper resolve () que o Laravel oferece. Ele resolve um determinado nome de classe para sua instância usando o contêiner de serviço.
Existem algumas outras maneiras de chamar o método detect () da classe Spam, você pode fazer isso com dicas de tipo, criando uma nova instância da classe Spam e depois chamando o método detect () etc. No entanto, o método usado no código acima parece bom por enquanto.

 

Conclusão

O exemplo neste post é uma solução simples e fácil de implementar. Claro, como mencionado acima, existem muitas outras regras que você pode adicionar e, com essa estrutura de código, será muito fácil adicionar uma nova regra com base em suas necessidades.
Você pode ver como é agradável programar com o framework Laravel, é por isso que o Laravel é preferido e recomendado para todos os tipos de aplicações web, desde simples projetos de hobby até empresas Fortune 500.
Fique à vontade para comentar abaixo e compartilhar suas idéias.


1

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 1 Comments
  • Renato Lucena
    Renato Lucena - há 2 anos
    Link da fonte: - https://iwconnect.com/laravel-spam-detection-step-by-step-guide/

Blog Search


Categories

OUTROS (15) Variados (109) PHP (130) Laravel (158) Black Hat (3) front-end (28) linux (113) postgresql (39) Docker (27) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (54) devops (25) nodejs (5) npm (2) nvm (1) git (8) firefox (1) react (6) reactnative (5) collections (1) javascript (6) reactjs (7) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (1) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (11) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (4) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (1) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (40) Kubernetes (3) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (1) jwt (4) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (2) Architecture (3) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (1) autorizacao (2) authentication (4) authorization (2) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1)

New Articles



Get Latest Updates by Email