Intégration

Documentation

Plusieurs solutions d'intégration sont disponibles. Pour simplifier le travail des développeurs, nous mettons donc à disposition des libraires serveur et client.

Documentation

Composant serveur (Yii2)

Ce composant permet d'installer en quelques minutes tous les pré-requis serveur

NginX
Apache
Maria db
Mysql
Redis
PHP
Yii

Installation

install.sh
composer require blackcube/powshield

Configuration du module

Il est nécessaire d'éditer la configuration de l'application Yii2 pour activer le module

config.php
'bootstrap' => [
    // modules à bootstrapper
    // ...
    'powshield',
],
'modules' => [
// modules de votre application
// ...
    'powshield' => [
        'class' => blackcube\powshield\Module::class,
        'antiReplay' => true, // activer l'antireplay
        'antiReplayTimeout' => 300, // durée ou l'application va garder en mémoire les solutions brûlées
        'algorithm' => 'SHA-256', // algorithme de chiffrement
        'key' => 'sdfghjklmnbvcxwqertyuiop', // clef de chiffrement / déchiffrement
        'minIterations' => 0, // nombre minimal d'itérations nécessaires à la résolution du captcha
        'maxIterations' => 50000, // nombre maximal d'itérations nécessaires à la résolution du captcha
        'saltLength' => 12,
        'timeValidity' => 900, // durée de validité d'une solution
    ],
]

API

Une fois le module activé les endpoints

  • /powshield/generate-challenge
  • /powshield/verify-solution

sont disponibles

Modèle de validation

pour valider le CAPTCHA côté serveur, il est nécessaire de mettre le validateur

FormModel.php
namespace app\models;

use yii\base\Model;

class FormModel extends Model
{
    public $email;
    public $subject;
    public $message;
    public $captchaSolution;

    public function rules()
    {
        return [
            [['email', 'subject', 'message', 'captchaSolution'], 'required'],
            // validation du CAPTCHA
            [['captchaSolution'], 'powshield'],
        ];
    }
}

Composant front-end (Aurelia 2)

Ce composant permet d'installer les pré-requis client

Aurelia
Typescript
NPM

Installation

install.sh
npm install --save @blackcube/aurelia2-powshield
startup.ts
import Aurelia, { ConsoleSink, LoggerConfiguration, LogLevel } from 'aurelia';
import { PowshieldConfiguration} from '@blackcube/aurelia2-powshield';
import {Enhance} from "./app/enhance";

declare var webpackBaseUrl: string;
declare var __webpack_public_path__: string;
if ((window as any).webpackBaseUrl) {
    __webpack_public_path__ = webpackBaseUrl;
} else {
    __webpack_public_path__ = '';
}
declare var PRODUCTION:boolean;


const page = document.querySelector('body') as HTMLElement;
const au = new Aurelia();

    au.register(PowshieldConfiguration.configure({}));

    if(PRODUCTION == false) {
        au.register(LoggerConfiguration.create({
            level: LogLevel.trace,
            colorOptions: 'colors',
            sinks: [ConsoleSink]
        }));

    }

    au.enhance({
        host: page,
        component: Enhance
    });

Formulaire de saisie

et bien évidemment le formulaire de saisie pour l'internaute

form.php
use yii\helpers\Html;
use yii\helpers\Url;

echo Html::beginForm(Url::to(['form']), 'post', ['novalidate' => 'novalidate', 'bc-powshield' => '']);

echo Html::errorSummary($formModel);
echo Html::activeHiddenInput($formModel, 'captchaSolution', ['id' => 'powshieldSolution']);

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'email');
echo Html::activeInput('email', $formModel, 'email', ['placeholder' => 'Email *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Subject *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Message *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo Html::submitButton('Send');
echo Html::endTag('div');

echo Html::endForm();

Et voilà!

la magie opère grâce à plusieurs éléments:

l'attribut bc-powshield accroche le captcha au formulaire et le validateur powshield vérifie que tout est correct. suite à ces légères modifications, votre formulaire est protégé!

Composant front-end (Vanilla JS)

Ce composant permet d'installer les pré-requis client

Javascript
NPM

Installation

install.sh
npm install --save @blackcube/vanilla-powshield

Formulaire de saisie

et bien évidemment le formulaire de saisie pour l'internaute

form.php
use yii\helpers\Html;
use yii\helpers\Url;

echo Html::beginForm(Url::to(['form']), 'post', ['novalidate' => 'novalidate']);

echo Html::errorSummary($formModel);
echo Html::activeHiddenInput($formModel, 'captchaSolution', ['id' => 'powshieldSolution']);

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'email');
echo Html::activeInput('email', $formModel, 'email', ['placeholder' => 'Email *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Subject *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo HTml::activeLabel($formModel, 'subject');
echo Html::activeInput('email', $formModel, 'subject', ['placeholder' => 'Message *']);
echo Html::endTag('div');

echo Html::beginTag('div');
echo Html::submitButton('Send');
echo Html::endTag('div');

echo Html::endForm();

Gestion du formulaire

et un peu de code pour gérer la soumission du formulaire

form.js
import {Powshield} from '@blackcube/vanilla-powshield';

const powshield = new Powshield();

const form = document.querySelector('form');

if (form) {
    form.addEventListener('submit', function (event) {
        event.preventDefault();
        powshield.getChallenge('/powshield/generate-challenge')
            .then(challenge => {
                return powshield.solveChallenge(challenge)
            })
            .then(response => {
                console.log('challenge:', response);
                return powshield.solveChallenge(response)
            })
            .then(response => {
                console.log('solution:', response);
                const promises = [];
                promises.push(powshield.verifySolution('/powshield/verify-solution', response));
                promises.push(response);
                return Promise.all(promises);
            })
            .then(response => {
                const verified = response[0];
                const solution = response[1];
                console.log('verified:', solution);
                if (!verified) {
                    throw new Error('Solution is not verified');
                }
                const b64 = btoa(JSON.stringify(solution));
                return b64;
            })
            .then(response => {
                const hiddenField = document.getElementById('powshieldSolution');
                if (hiddenField) {
                    hiddenField.value = response;
                    // finally submit form
                    event.target.submit();
                } else {
                    throw new Error('Hidden field not found');
                }
                console.log('encoded:', response);
            })
    });
}