Módulo – Utilização
O serviço do CAPTCHA é chamado via GET HTTP, e devolve uma resposta em json.
Atualmente permite 2 tipos de desafio:
- Imagem – Imagem com um desafio
- Som – Geração do desafio com som
- QA: https://hubservicos.qrnsi.local/skaptcha
- Prod: https://hubservicos.mai.gov.pt/skaptcha
Informação inicial
Para utilizar o CAPTCHA é necessária a criação de uma private key e uma public key deverá ser enviado no header das chamadas por forma a poder executar os vários métodos. Tem assim de se pedir a criação das mesmas indicando o ambiente e a aplicação onde se pretende colocar.
As keys estão ligadas a uma entidade e um URL de domínio e isso determina aonde poderão utilizar a solução.
A sua utilização consiste no seguinte:
-
Acrescentar à página onde se pretende utilizar o CAPTCHA o seguinte:
- Include do script skaptcha.js <script src="CAPTCHA_URI/Content/skaptcha.js"> </script>
- Include do css skaptcha.css <link href="CAPTCHA_URI/Content/skaptcha.css" rel="stylesheet">
- Div onde irá o Captcha aparecer com id especifico
- Chamada no Document.ready do método getnewchallenge
- Include do script skaptcha.js
- Acrescentar ao POST do submit a chamada ao método do VerifyChallengePost
Script skaptcha.js
Este script é utilizado para a chamada ao método getnewchallenge.
Tem 4 variáveis globais que podem ser preenchidas à priori para definir o browser, a Timezone, o tipo de device e o tipo de IP, através dos método defineBrowserAndIpType ou defineAllValuesEntry
Caso assim não aconteça, o js tem métodos para as calcular.
Método defineBrowserAndIpType
Parâmetros de entrada:
Campo | Formato | Obrigatório | Descrição | Regras de negócio |
---|---|---|---|---|
browser | long | Sim | Browser cliente |
1 Não definido 2 Chrome 3 Edge 4 Internet Explorer 5 Safari 6 Firefox 7 Opera 8 Outro |
ipTypeId | long | Sim | Tipo de IP |
1 Não definido 2 Nacional 3 Estrangeiro |
Método defineAllValuesEntry
Parâmetros de entrada:
Campo | Formato | Obrigatório | Descrição | Regras de negócio |
---|---|---|---|---|
browser | long | Sim | Browser cliente |
1 Não definido 2 Chrome 3 Edge 4 Internet Explorer 5 Safari 6 Firefox 7 Opera 8 Outro |
ipTypeId | long | Sim | Tipo de IP |
1 Não definido 2 Nacional 3 Estrangeiro |
deviceTypeId | long | Sim | Tipo de Device |
1 Não definido 2 Mobile 3 PC |
timezone | string | Sim | timezone |
Método getnewchallenge
Este método serve para a chamada do desafio
Parâmetros de entrada:
Campo | Formato | Obrigatório | Descrição | Regras de negócio |
---|---|---|---|---|
key | string | Sim | Chave pública do desafio | |
sound | bool | Não | Desafio têm som ou não | Apenas é gerado um desafio com som quando o mesmo é pedido, caso contrário não haverá som |
culture | string | Não | Cultura, implementação feita em PT e EN | Assumindo PT como default caso não receba indicação |
hostUrl | string | Sim | URL da API do Captcha | |
clientDiv | string | Sim | Div onde irá o Captcha aparecer | |
browserId | long | Sim | Id do browser como explicado acima | |
ipTypeId | long | Sim | Id do tipo de IP como explicado acima | |
deviceTypeId | long | Sim | Id do tipo de device como explicado acima | |
timezone | string | Sim | timezone |
Método VerifyChallengePost
Este método devolve o resultado perante o desafio proposto.
Parâmetros de entrada:
Campo | Formato | Obrigatório | Descrição | Regras de negócio |
---|---|---|---|---|
key | string | Sim | Chave privada do desafio | |
id | string | Sim | Id do desafio | Encontra-se no campo captchaId |
answer | string | Sim | Input do desafio feito pelo utilizador |
Parâmetros de saída:
Campo | Formato | Obrigatório | Descrição | Regras de negócio |
---|---|---|---|---|
IsCorrect | bool | Sim | Devolve o resultado da resposta está correcto |
Exemplo de HTML
Atenção as variáveis a vermelho que variam consoante a aplicação.
O captcha_uri a utilizar depende do ambiente e está relacionado com os urls indicado no "Módulo - utilização".
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"> </script>
<script src="CAPTCHA_URI/Content/skaptcha.js"> </script>
<link href="CAPTCHA_URI/Content/skaptcha.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<meta name="viewport" content="width=device-width">
<title>Login</title>
</head>
<body>
<div id="login-div">
<form action="/" method="post">
<div class="container">
<table style="margin: auto; margin-bottom: 20px; margin-top: 20px; ">
<tbody>
<tr>
<td colspan="2" style="text-align:center;"> <h1 class="h3 mb-3 fwnormal">Login Skaptcha </h1> </td>
</tr>
<tr>
<td>
<label for="Name" htmlattributes="{ class = form-label }">Nome </label>
</td>
<td>
<input class="form-control text-box single-line" id="Name" name="Name" type="text" value="">
</td>
</tr>
<tr>
<td>
<label for="Password" htmlattributes="{ class = form-label}">Password </label>
</td>
<td>
<input class="form-control text-box single-line" id="Password" name="Password" type="text" value="">
</td>
</tr>
</tbody>
</table>
<div class="container" id="SkaptchaContainer"></div>
<table style="margin:auto;">
<tbody>
<tr>
<td>
<input type="submit" name="name" value="Login" class="btn btn-primary">
<input type="reset" name="name" value="Limpar" class="btn btnsecondary">
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
<script>
//caso se pretenda definir as variáveis ipTypeIdSkaptcha e browserSkaptcha tem de ser feito antes de realizar a chamada do getNewChallenge
$(document).ready(function ()
{
//exemplo de preenchimento das variaveis browserSkaptcha e ipTypeIdSkaptcha do skaptcha.js
//var browser=4;
//var ipTypeId=3;
//defineBrowserAndIpType(browser, ipTypeId);
if (fromPost)
{
if (answerIsCorrect)
{
alert("A resposta ao desafio não está correta");
getNewChallenge("PUBLIC_KEY", "", "", "CAPTCHA_URI", "SkaptchaContainer");
}
else
{
alert("A resposta ao desafio não está correta");
getNewChallenge("PUBLIC_KEY", "", "", "CAPTCHA_URI", "SkaptchaContainer");
}
}
else
{
getNewChallenge("PUBLIC_KEY", "", "", "CAPTCHA_URI", "SkaptchaContainer");
}
});
</script>
</body>
</html>
Exemplo no Controlador
Atenção as variáveis a vermelho que variam consoante a aplicação.
O captcha_uri a utilizar depende do ambiente e está relacionado com os urls indicado no "Módulo - utilização".
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.Mvc;
namespace ClientTest.Controllers
{
public class ChallengeModel
{
public bool IsCorrect { get; set; }
}
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(FormCollection model)
{
if (model != null)
{
string answer = model["captchaResponse"];
bool isParsed = Int64.TryParse(model["captchaId"], out long captchaId);
if (isParsed)
{
string url = "CAPTCHA_URI"
HttpClient apiClient = new HttpClient();
apiClient.BaseAddress = new Uri(url);
ViewBag.FromPost = true;
ViewBag.AnswerIsCorrect = false;
string privateKey = "PRIVATE_KEY";
ChallengeModel challengeModel = this.VerifyChallengePost(privateKey, captchaId,answer, apiClient);
if (challengeModel != null)
{
if (challengeModel.IsCorrect)
{
ViewBag.AnswerIsCorrect = true;
}
}
}
}
return View();
}
private ChallengeModel VerifyChallengePost(string key, long id, string answer, HttpClient apiClient)
{
ChallengeModel challengeModel = null;
if (id > 0)
{
string completeUrl = apiClient.BaseAddress + "api/Captcha/VerifyChallengePost";
using (var client = new HttpClient())
{
var formcontent = new FormUrlEncodedContent(new[]
{
new KeyValuePair("key",key),
new KeyValuePair("id", id.ToString()),
new KeyValuePair("answer",answer)
});
var responseTask = client.PostAsync(new Uri(completeUrl), formcontent);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync();
readTask.Wait();
challengeModel = readTask.Result;
}
else //web api sent error response
{
throw new Exception(result.ReasonPhrase);
}
}
}
return challengeModel;
}
}
}