궁금한게 많은 열아홉
article thumbnail

개요

지난 포스팅에서 QR코드를 생성하고, 이를 이미지화 하는 작업까지 마쳤다. 그래서 오늘은 이를 활용해 입소 인증기능을 구현해볼 예정이다. 필자는 현재 프로젝트에서 Next.js와 Typescript를 활용해서 진행하고 있다.

기능사항 쪼개기

우선 내가 구현하고자 하는 기능을 세부사항으로 쪼갰다. 그랬더니, 아래와 같이 4가지 사항들로 정리할 수 있었다. 

  1. react-qr-reader라이브러리 설치하기
  2. qr을 스캔하는 컴포넌트 생성하고, 설정해주기
  3. 카메라를 통해 QR코드 인식하기
  4. 결과를 확인하고 통과시키기

그럼 이제 시작해보도록하자.

react-qr-reader 설치하기

npm i react-qr-reader

yarn add react-qr-reader

 

npm 혹은 yarn을 활용해 react-qr-reader 라이브러리를 설치해준다. 공식문서는 보이지 않았고, 필자는 npmjs를 참고했다.

package.json에서 설치된 것을 확인할 수 있다.

 

qr을 스캔하는 컴포넌트 생성하고, 설정해주기

우선 잘못 인식하는 것을 최소화하기 위해 인증 시작하기 버튼을 생성해주었다.

startScan이라는 상태값을 하나 만들고 false로 초기화를 해주었다.

import React, { useState } from "react";

export const Qrscan = () => {
  const [startScan, setStartScan] = useState<boolean>(false);

  return (
    <div className="text-center">
      <button
        className="w-[130px] h-[40px]"
        onClick={() => {
          setStartScan(!startScan);
        }}
      >
        {startScan ? "인증 그만하기" : "인증 시작하기"}
      </button>
    </div>
  );
};

 

그리고 startScan이 true일 때 카메라가 나타나도록 조건부 렌더링을 해주었다.

import axios, { AxiosResponse } from "axios";
import { useRouter } from "next/router";
import React, { useState } from "react";
import { QrReader } from "react-qr-reader";

export const Qrscan = () => {
  const [startScan, setStartScan] = useState<boolean>(false);

  return (
    <div className="text-center">
      <button
        className="w-[130px] h-[40px]"
        onClick={() => {
          setStartScan(!startScan);
        }}
      >
        {startScan ? "인증 그만하기" : "인증 시작하기"}
      </button>

      {startScan && (
        <div className="pt-20">
          <QrReader
            scanDelay={1000}
            onResult={(result, error) => {
              if (result) {
                console.log(`loaded >>>`, result.getText());
              }
              if (!!error) {
                console.log("error", error);
              }
            }}
            className="m-auto w-[500px] h-[200%] border-4"
          />
        </div>
      )}
    </div>
  );
};

 

그리고 Qrreader 위쪽에 select 옵션을 넣어 전/후면 카메라를 넣어주었다.

<select onChange={(e) => setSelected(e.target.value)}>
            <option value={"environment"}>후면 카메라</option>
            <option value={"user"}>전면 카메라</option>
</select>

 

 

카메라를 통해 QR코드 인식하기

이제 만들어 둔 QR 코드를 인식해 줄 차례다. 미리 파이썬으로 만들어진 QR코드를 하나 가져온다.

 

qr

 

그리고 QR데이터의 문자열 값을 받았을 때, handleData 함수를 통해 결과를 어떻게 처리할지 작성해준다.

import axios, { AxiosResponse } from "axios";
import { useRouter } from "next/router";
import React, { useState } from "react";
import { QrReader } from "react-qr-reader";

export const Qrscan = () => {
  const router = useRouter();
  const [selected, setSelected] = useState<string>("environment");
  const [startScan, setStartScan] = useState<boolean>(false);
  const [data, setData] = useState<string>("");

  const handleData = async (data: string) => {
    const response: AxiosResponse = await axios.post("/api/random", { qrstring: data });

    if (response.data.message === "fail") {
      alert("인증 시간이 지났습니다");
      router.push("/qrscan");
    } else {
      alert("인증이 완료되었습니다");
      router.push("/main")
    }
  };

  return (
    <div className="text-center">
      <button
        className="w-[130px] h-[40px]"
        onClick={() => {
          setStartScan(!startScan);
        }}
      >
        {startScan ? "인증 그만하기" : "인증 시작하기"}
      </button>

      {startScan && (
        <div className="pt-20">
          <select onChange={(e) => setSelected(e.target.value)}>
            <option value={"environment"}>후면 카메라</option>
            <option value={"user"}>전면 카메라</option>
          </select>
          <QrReader
            scanDelay={1000}
            constraints={{ facingMode: selected }}
            onResult={(result, error) => {
              if (result) {
                setData(result.getText());
                handleData(result.getText());
              }
              if (!!error) {
                console.log("error", error);
              }
            }}
            className="m-auto w-[500px] h-[200%] border-4"
          />
        </div>
      )}
    </div>
  );
};

 

다음으로 이렇게 QR코드를 인식하면

 

이렇게 통과되었다는 알림을 띄워줄 수 있다.

profile

궁금한게 많은 열아홉

@jjin502

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!