SKAPTCHA – Documentação Técnica da API

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
Os urls atuais são:
  • 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
  • Acrescentar ao POST do submit a chamada ao método do VerifyChallengePost
Nota: O captcha_uri a utilizar depende do ambiente e está relacionado com os urls indicado no "Módulo - utilização".

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;
}
}
}