reCAPTCHA와 Next.js 통합
27785 단어 reactjavascriptprogrammingnextjs
그러나 시작하기 전에 먼저 reCAPTCHA의 작동 방식을 파악해 보겠습니다. 문의 양식이 있는 포트폴리오 웹 사이트를 구축했지만 실제 메시지를 받는 대신 많은 스팸을 받았다고 가정합니다. 이러한 스팸 메시지는 봇에 의해 생성되었습니다. 봇을 차단하기 위해 reCAPTCHA를 활용합니다.
지금 바로 실행해 보겠습니다. 먼저 이 웹사이트로 이동하여 관련 정보로 양식을 작성합니다(아래 참조).
양식을 제출하면 사이트 키(브라우저에서 볼 수 있음)와 비밀 키가 제공됩니다. 아래와 같이 .env.local에 추가하십시오.
이제 reCAPTCHA를 Next.js 12와 통합하기 시작합니다.
프로젝트 레포(개인 포트폴리오 사이트입니다):- https://github.com/Sumukha210/new-portfolio-website
다른 종속성과 함께 Next.js 설치,
npx create-next-app@latest --typescript
또는
yarn create next-app --typescript
그런 다음 이 패키지를 추가하고
yarn add react-google-recaptcha-v3
이 코드를 _app.tsx(또는 .jsx) 파일에 추가하세요. 여기서 우리는 구성 요소를 GoogleRecaptchaProvider로 래핑합니다.
import type { AppProps } from "next/app";
import "@/styles/styles.scss";
import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
function MyApp({ Component, pageProps }: AppProps) {
return (
<GoogleReCaptchaProvider
reCaptchaKey={process.env.NEXT_PUBLIC_RECAPTHA_SITE_KEY}
scriptProps={{
async: false, // optional, default to false,
defer: true, // optional, default to false
appendTo: "body", // optional, default to "head", can be "head" or "body",
nonce: undefined,
}}>
<Component {...pageProps} />;
</GoogleReCaptchaProvider>
);
}
export default MyApp;
이제 양식을 배치한 페이지에 이 코드를 추가하십시오. 여기서는 먼저 useGoogleRecaptcha hook을 가져오고 양식이 확인되면 reCAPTCHA가 로드되었는지 여부를 확인하고 있으면 함수에서 반환합니다. 오류가 없으면 다른 데이터와 함께 토큰을 서버로 보냅니다.
import React, { useState } from "react";
import { useGoogleReCaptcha } from "react-google-recaptcha-v3";
import { Wrapper, SubmitBtn } from "./RightSectionStyles";
import axios from "axios";
import { responseTypes } from "@/utils/types";
const RightSection = () => {
const [isBtnDisabled, setBtnDisabled] = useState(false);
const { executeRecaptcha } = useGoogleReCaptcha();
const [response, setResponse] = useState<responseTypes | null>(null);
const handleSubmit = async (e: any) => {
e.preventDefault();
const name = e.target[0];
const email = e.target[1];
const message = e.target[2];
[name, email, message].forEach(item => {
if (item.validity.valid === false && item.validity.valid) {
return;
}
});
setBtnDisabled(true);
if (!executeRecaptcha) {
return;
}
try {
const token = await executeRecaptcha();
if (!token) {
setResponse({ message: "Failed to Send!!!", status: "Failed" });
return;
}
const result = await axios.post("/api/contactUs", {
token,
name: name.value,
email: email.value,
message: message.value,
});
console.log(result);
if (result.data) {
setResponse({
message: result.data.message,
status: result.data.status,
});
}
setBtnDisabled(false);
} catch (error) {
console.log(error);
setResponse({ message: "Failed to Send!!!", status: "Failed" });
setBtnDisabled(false);
}
};
return (
<Wrapper>
<form onSubmit={handleSubmit}>
<div className="flex">
<section>
<input
type="text"
placeholder="Enter your name"
name="name"
required
/>
</section>
<section>
<input
type="email"
placeholder="Enter your email"
name="email"
required
/>
</section>
</div>
<section>
<textarea
name="message"
placeholder="Enter your message"
cols={30}
rows={10}></textarea>
</section>
<div className="responseText">
<h3
className="subtitle-4"
style={{
color: response?.status === "Failed" ? "red" : "#24ff72",
}}>
{response?.message}
</h3>
</div>
<div className="btnContainer">
<SubmitBtn disabled={isBtnDisabled} type="submit" marginTop="2rem">
<span>Submit{isBtnDisabled && "ting"}</span>
{isBtnDisabled && <span className="loader"></span>}
</SubmitBtn>
</div>
</form>
</Wrapper>
);
};
export default RightSection;
/pages/api에서 새 파일(엔드포인트) contactUs.ts를 생성하고 이 코드를 추가합니다.
import { responseTypes } from "@/utils/types";
import axios from "axios";
import type { NextApiRequest, NextApiResponse } from "next";
const verifyRecaptcha = async token => {
const secretKey = process.env.RECAPTHA_SECRET_KEY;
var verificationUrl =
"https://www.google.com/recaptcha/api/siteverify?secret=" +
secretKey +
"&response=" +
token;
return await axios.post(verificationUrl);
};
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<responseTypes>
) {
try {
const name = req.body.name;
const email = req.body.email;
const message = req.body.message;
const token = req.body.token;
// Recaptcha response
const response = await verifyRecaptcha(token);
// Checking if the reponse sent by reCaptcha success or not and if the score is above 0.5
// In ReCaptcha v3, a score sent which tells if the data sent from front end is from Human or from Bots. If score above 0.5 then it is human otherwise it is bot
// For more info check, https://developers.google.com/recaptcha/docs/v3
// ReCaptcha v3 response, {
// "success": true|false, // whether this request was a valid reCAPTCHA token for your site
// "score": number // the score for this request (0.0 - 1.0)
// "action": string // the action name for this request (important to verify)
// "challenge_ts": timestamp, // timestamp of the challenge load (ISO format yyyy-MM-dd'T'HH:mm:ssZZ)
// "hostname": string, // the hostname of the site where the reCAPTCHA was solved
// "error-codes": [...] // optional
// }
if (response.data.success && response.data.score >= 0.5) {
return res
.status(200)
.json({ status: "Success", message: "Thank you for contacting me." });
} else {
return res.json({
status: "Failed",
message: "Something went wrong, please try again!!!",
});
}
} catch (error) {
console.log("ERRRRROr", error);
res.json({
status: "Failed",
message: "Something went wrong, please try again!!!",
});
}
}
Reference
이 문제에 관하여(reCAPTCHA와 Next.js 통합), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sumukhakb210/integrating-recaptcha-with-nextjs-4ig6텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)