수기로 작성하는 기존의 출석체크는 시간과 노력을 소비하며, 실수할 확률이 높다. 나는 이를 개선하고자 선생님들께서 각 자리를 돌아다니며 책생에 붙어있는 QR코드만 찍으면 되는 출석체크 웹애플리케이션을 개발하게되었다. 이 웹 애플리케이션을 사용하면 선생님들께서 QR코드만 찍으면 되서 시간과 노력을 절약할 수 있고, 출석체크를 하는 과정이 전보다 훨씬 간단해져, 우리학교 학생들의 공부 효율 증진도 기대해 볼 수 있다.
HTML5에서 QR코드를 읽을 수 있는 오픈 소스 프로젝트인 html5-QRCode를 이용하여 QR코드에 저장 되어있는 좌석번호를 스캔한 후 스캔한 좌석번호를 MariaDB에서 검색하여 저장되어있는 학생정보를 가져온 후 가져온 학생정보와 현재시간을 MariaDB에 저장하는 구조이다.
위 다이어그램은 출결 표시 요청이 들어오면 서버가 응답하는 방식을 간략하게 나타낸 그림이다.
표를 생성하라는 사용자의 요청이 오면 표의 각 열에 좌석번호가 있고, 좌석번호를 가지고 MariaDB에서 좌석번호를 검색하여 그 좌석번호에 등록된 학생정보와 출석데이터를 불러와서 표를 생성한다.
선생님 관리자 페이지를 접속하려면 비밀번호가 필요하다.
어떤 악의적인 사용자가 무차별 대입(Brute Force)공격 기법을 사용하여 비밀번호를 알아낸다는 취약점이 있었다.
그래서 한 IP와 PHP의 셰션을 이용하여 해결 하였다. 한 IP와 방문자의 웹브라우저 정보를 분석하여 1분동안 10번 정도의 로그인 시도 횟수가 넘으면 차단이 되게 하여 IP 블랙리스트에 등록이되어 관리자가 블랙리스트에서 삭제를 하지 않는 한 계속 차단이 되어 접속 자체를 못하게 하였다.
이제 개발이 끝난 후 여름 방학 자습시간에 테스트를 했다.
QR코드에는 각 자리의 좌석번호가 저장되어있었는데, 여기서 만약 좌석번호의 QR코드를 찍지 않고 다른 QR코드를 찍은다면 오류가 발생하여 중간에 로직이 멈추는 버그가 발생하였다.
// 이전에 사용한 카메라 ID를 저장하는 변수
let previousCameraId = null;
function onScanSuccess(qrCodeMessage) {
// QR코드가 정수로만 이루어졌는지 확인
if (/^\d+$/.test(qrCodeMessage)) {
document.getElementById('result').textContent = qrCodeMessage;
// 페이지 이동
window.location.href = 'https://study.wonchan.net/process_qrcode.php?qrcode=' +
encodeURIComponent(qrCodeMessage);
// 인식 후 스캐너 중지
html5QrcodeScanner.clear();
} else {
// 정수가 아닌 경우 다시 찍으라고 안내
document.getElementById('result').textContent = "올바르지 않은 QR코드 입니다";
}
}
// 카메라 선택 이벤트 핸들러
function onCameraSelection(cameraId) {
// 이전에 사용한 카메라 ID 저장
previousCameraId = cameraId;
// QR 코드 스캐너 렌더링
html5QrcodeScanner.render(onScanSuccess, {
// 한 번만 인식하도록 설정
continuous: false,
// 이전에 사용한 카메라 선택
deviceId: cameraId
});
}
var html5QrcodeScanner = new Html5QrcodeScanner(
"qr-reader", {
fps: 30,
qrbox: 250,
// 카메라 선택 이벤트 핸들러 등록
cameraSelectionCallback: onCameraSelection
});
// 이전에 사용한 카메라가 있는 경우 해당 카메라 선택
if (previousCameraId !== null) {
html5QrcodeScanner.render(onScanSuccess, {
continuous: false,
deviceId: previousCameraId
});
} else {
// 처음 페이지에 접속한 경우 스캐너 렌더링
html5QrcodeScanner.render(onScanSuccess);
}
(qr코드 인식 자바스크립트)
버그의 원인을 분석하였다. 원인은 QR코드를 읽고 읽은 값이 INT가 아니라 String을 읽었을때 오류가 발생하여 멈추는 것이였다.
먼저 이 오류를 해결하기 위해 생각한 것은 QR코드를 읽고 서버로 전송하고 서버에서 클라이언트에서 받은 값이 인지 INT인지 String인지 확인하는 방법을 생각하였다. 처음에는 금방 해결 할 수 있었지만 서버에 로직이 생각보다 복잡해져서 이 방법을 사용하지 못 하였다.
그래서 2번째로 생각을 해낸 방법이 클라이언트에서 데이터타입을 구분해내는 것이다. 클라이언트의 QR코드를 읽는 자바스크립트 코드의 6번째 줄을 수정하여 QR코드를 읽었을 때 데이터타입이 INT형인지, String인지 확인하는 코드를 추가하였고,만약 String 형이라면 "올바르지 않은 QR코드입니다."라고 출력하도록 코드를 작성했다. 이러한 방법으로 문제를 해결하였다.
이제 성공적으로 여름방학 출석체크를 마치고 표가 나왔다. 선생님께서 생성된 표를 엑셀로 저장 및 인쇄를 할 수 있는 기능이 있으면 좋겠다고 나에게 피드백을 해주셨다.
첫번째로 엑셀로 저장하는 기능을 만들었다.
오픈소스 프로젝트 Sheet.js를 이용하여 만들었다. HTML 표를 만드는 태그인 Table 태그의 시작점과 끝점을 선택하여 Sheet.js이 예제 코드를 참고해 응용하여 만들었다.
두번째로 인쇄 기능을 만들었다.
인쇄기능도 마찬가지로 오픈소스 프로젝트인 html2canvas를 이용하여 만들었다. 위 엑셀로 저장하는 과정과 마찬가지로 Table태그의 시작점과 끝점을 선택하여 이미지로 저장한 후 그것을 인쇄를 하는 버튼을 연결하여 만들었다.
PHP, MariaDB, Nginx 등을 활용하여 QR코드 기반을 출석체크 웹애플리케이션을 개발하였는데 개발 도중 약간의 고난과 어려움이 있었지만 포기하지 않고 만들었다. 이를 통해 출석체크 과정의 시간과 노력소비를 줄이고, 높은 효율 및 편의성을 제공하는 웹 애플리키에션을 만들었다.
향후 계획에서는 이 웹 애플리케이션을 주로 사용하시는 선생님, 학생들의 피드백을 수집하여 이 웹 애플리케이션을 더 완성되고 완벽한 출석 체크 웹 애플케이션으로 만들겠다. 그리고 해킹에 의한 사고는 현재까지 발생되지 않았지만 계속 이 웹 애플리케이션을 모니터링하여 보안 취약점을 해결하고 학생들의 개인정보가 노출되지 않게 할 것이다. 그리고 현재 출석체크 웹 애플리케이션을 1학년 밖에 도입이 안 되어있는데, 아직 도입을 안한 2,3학년도 도입을 하도록 추진해 봐야겠다.
(2023학년도 세부능력특기사항을 쓰기위한 보고서를 기반으로 작성한 글입니다.)