Node로 인증 코드 생성기를 만듭니다.회사 명
24715 단어 nodewebdevtutorialjavascript
본문의 원본 코드를 찾으려면 healeycodes/captcha-api 를 방문하십시오.
스팸 솔루션
고객이 로봇 스팸메일 솔루션을 필요로 한다고 상상해 봅시다.그들은 그림과 텍스트 문자열을 필요로 한다.너는 네가 우울하게 해결하지 못한 종잡을 수 없는 자모와 숫자를 떠올릴 것이다.그럼에도 불구하고, 너는 이 임무에 동의한다.
이 고객은 일련의 사이트를 가지고 있다.서로 다른 곳에는 서로 다른 크기의 검증 코드가 필요하다.그것들은 너비와 높이를 제공할 것이다.이것은 우리 API의 규범을 설명한다.
JavaScript는 이미지를 생성하는 데 매우 적합합니다Canvas API.나는 항상 내가 곤경에 빠졌을 때, 그것은 많은 Stackoverflow 내용과 함께 편리하게 사용할 수 있다는 것을 발견한다.
우리는 브라우저에서 인증 코드를 만들고 싶지 않다. 왜냐하면 우리가 막으려는 로봇은 원본 코드를 검사하고 메모리의 값을 찾으며 각종 까다로운 정책을 시도할 수 있기 때문이다.
하나의 노드.js 서비스
백엔드로 이동해서 필요에 따라 호출할 수 있는 서비스로 이동합시다.웹 API 없이 웹 API에 액세스하는 문제를 이미 node-canvas 또는
npm i canvas
로 해결한 사람이 있습니다.[canvas] is an implementation of the Web Canvas API and implements that API as closely as possible.
우리는 매번 무작위 텍스트를 생성해야 한다.우리들은 두 개의 함수를 써서 우리를 돕는다.우리의 API에 대해 우리는 논리를 하나의 일을 하는 함수로 분해하여 최종 결과가 추리와 유지보수가 쉽도록 할 것이다.
/* captcha.js */
// We'll need this later
const { createCanvas } = require("canvas");
// https://gist.github.com/wesbos/1bb53baf84f6f58080548867290ac2b5
const alternateCapitals = str =>
[...str].map((char, i) => char[`to${i % 2 ? "Upper" : "Lower"}Case`]()).join("");
// Get a random string of alphanumeric characters
const randomText = () =>
alternateCapitals(
Math.random()
.toString(36)
.substring(2, 8)
);
캔버스 안의 텍스트를 자동으로 축소할 수 없기 때문에 (브라우저에서 우는 것처럼) 우리도 약간의 보조 기능이 필요하다.인증 코드의 길이와 텍스트가 이미지에 있는 위치를 확인하려면 테스트를 해야 할 수도 있습니다.다음은 내가 전에 준비한 변수들이다.const FONTBASE = 200;
const FONTSIZE = 35;
// Get a font size relative to base size and canvas width
const relativeFont = width => {
const ratio = FONTSIZE / FONTBASE;
const size = width * ratio;
return `${size}px serif`;
};
이렇게 하면 텍스트를 축소할 수 있다. 캔버스의 비율이 변하지 않는다면 우리는 비슷한 그림을 볼 수 있다.본고에서 우리는 텍스트를 회전하고 싶지만 로봇에게 숨기기 위해 텍스트를 왜곡할 수 있는 방법이 많다. 나는 네가 무엇을 생각해 낼 수 있는지 보고 싶다.
캔버스를 회전할 때 우리가 전달하는 값은 radians 이기 때문에 우리는 무작위 곱하기
Math.PI / 180
를 해야 한다.// Get a float between min and max
const arbitraryRandom = (min, max) => Math.random() * (max - min) + min;
// Get a rotation between -degrees and degrees converted to radians
const randomRotation = (degrees = 15) => (arbitraryRandom(-degrees, degrees) * Math.PI) / 180;
나는 더 이상 조수 기능이 없다고 보증한다.우리는 이제 진정한 토론을 시작해야 한다.논리는 두 가지 기능으로 나뉜다.configureText
캔버스 대상을 가져와 무작위 텍스트를 추가하고 가운데에 놓는다.generate
폭과 높이를 취하다(우리가 제시한 규격을 기억하십니까?)PNG 이미지Data URL의 인증 코드를 반환합니다.Data URLs, URLs prefixed with the
data:
scheme, allow content creators to embed small files inline in documents.
// Configure captcha text
const configureText = (ctx, width, height) => {
ctx.font = relativeFont(width);
ctx.textBaseline = "middle";
ctx.textAlign = "center";
const text = randomText();
ctx.fillText(text, width / 2, height / 2);
return text;
};
// Get a PNG dataURL of a captcha image
const generate = (width, height) => {
const canvas = createCanvas(width, height);
const ctx = canvas.getContext("2d");
ctx.rotate(randomRotation());
const text = configureText(ctx, width, height);
return {
image: canvas.toDataURL(),
text: text
};
};
우리는 generate
이외의 모든 함수를 다른 곳에서 사용하지 말아야 할 사유 함수로 간주할 수 있기 때문에 이 함수만 내보낼 수 있다.module.exports = generate;
Express에서 제공하는 API
지금까지 우리는 이미지 생성 논리를 포함하는 파일
captcha.js
을 가지고 있다.이 기능을 다른 사람이 호출할 수 있도록 HTTP API를 통해 서비스를 제공합니다.Express는 이러한 작업 중 가장 많은 커뮤니티 지원을 받았습니다.저희가 진행할 노선은 다음과 같습니다.
/test/:width?/:height?/
/captcha/:width?/:height?/
Express 응용 프로그램 전문:
/* app.js */
const captcha = require("./captcha");
const express = require("express");
const app = express();
// Human checkable test path, returns image for browser
app.get("/test/:width?/:height?/", (req, res) => {
const width = parseInt(req.params.width) || 200;
const height = parseInt(req.params.height) || 100;
const { image } = captcha(width, height);
res.send(`<img class="generated-captcha" src="${image}">`);
});
// Captcha generation, returns PNG data URL and validation text
app.get("/captcha/:width?/:height?/", (req, res) => {
const width = parseInt(req.params.width) || 200;
const height = parseInt(req.params.height) || 100;
const { image, text } = captcha(width, height);
res.send({ image, text });
});
module.exports = app;
이 Express 응용 프로그램이 내보내졌으므로 테스트할 수 있습니다.우리의 API는 이 점에서 기능적이다.우리가 해야 할 일은 다음과 같은 문서 처리 서비스를 제공하는 것이다./* server.js */
const app = require("./app");
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`captcha-api listening on ${port}!`));
네비게이션 http://localhost:3000/test
은 우리에게 기본적인 인증 코드를 제공할 것입니다.생략하면 브라우저에 body
및 html
태그가 추가됩니다.유효한 데이터 URL
테스트를 쓸 때가 되었지만, 우선 당신의 것을 내려놓으세요unwieldy regular expressions.한 가지library가 이미 이 문제를 해결했다.
valid-data-url
통조림에 적힌 대로 완전히 만든다.나는 제스트를 나의 테스트 주자로 사용하는 것을 좋아한다.그것이 줄곧 나에게 효과가 있는 것 외에 다른 원인은 없다. 그것이 작용하지 않을 때, 나는 답을 찾을 수 있다.내 설정은 다음과 같이
scripts
에서 package.json
키를 설정합니다. "scripts": {
"test": "jest"
}
이렇게 하면 입력할 수 있습니다 npm test
.Jest는 모든 테스트를 찾아 실행합니다.우리 프로그램의 테스트 파일은 Express 응용 프로그램 대상을 가져오고
supertest
를 사용하여 HTTP 요청을 시뮬레이션합니다.우리는 비동기/대기 문법을 사용하여 리셋을 줄인다./* app.test.js */
const request = require("supertest");
const assert = require("assert");
const validDataURL = require("valid-data-url");
const app = require("../app");
describe("captcha", () => {
describe("testing captcha default", () => {
it("should respond with a valid data URL", async () => {
const image = await request(app)
.get("/captcha")
.expect(200)
.then(res => res.body.image);
assert(validDataURL(image));
});
});
describe("testing captcha default with custom params", () => {
it("should respond with a valid data URL", async () => {
const image = await request(app)
.get("/captcha/300/150")
.expect(200)
.then(res => res.body.image);
assert(validDataURL(image));
});
});
});
이 응용 프로그램의 크기를 고려하여 나는 그것을 두 개의 통합 테스트에 남기는 것에 만족한다.GitHub 워크플로우와의 지속적인 통합
표준 npm 테스트 명령
npm test
을 사용하여 저장소를 구성하기 때문에 몇 번 클릭하면 GitHub 워크플로우를 만들 수 있습니다.이렇게 하면 우리의 응용 프로그램은 코드를 전송할 때마다 구축하고 테스트할 것이다.지금 저희가 귀여운 휘장을 가지고 자랑합니다!
150여 명이 가입해 저의 newsletter 프로그램과 개인 성장!
나는 트위터에 과학 기술을 이야기했다.
Reference
이 문제에 관하여(Node로 인증 코드 생성기를 만듭니다.회사 명), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/healeycodes/let-s-build-a-captcha-generator-with-node-js-165i텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)