참고: https://www.section.io/engineering-education/password-strength-checker-javascript/
비밀번호는 애플리케이션 보안에서 매우 중요합니다. 누구나 자신의 시스템과 계정을 보호하기 위해 강력한 암호가 필요합니다. 이 포스트에서는 최종 사용자가 JavaScript의 정규식을 사용하여 계정을 보호할 수 있을 만큼 강력한 암호를 선택했는지 확인하는 방법에 대해 설명 하겠습니다.
정규표현식
정규식은 문자열의 문자 조합을 매치하는 데 사용하는 패턴입니다. JavaScript에서 정규식은 객체이기도 하고 RegExp로도 표시합니다. 이는 다음과 같이 구성할 수 있습니다:
- 패턴을 두개의 슬래시로 묶은 정규식 리터럴
let check = /vet/
- RegExp() 클래스의 생성자를 통해 확인할 문자열 전달
let check = new RegExp('vet');
패턴이 계속 변경되거나 패턴을 사용자의 입력에서 가져올 경우 생성자 함수를 사용합니다. 이번에는 사용자로부터 비밀번호를 얻을 것이므로 생성자 기능을 사용하겠습니다.
Patterns
패턴 | 의미 |
\d | 숫자가 일치하는지 확인(예: "U2"에서 2 리턴) |
\W | 특수문자 확인(예: "2%"에서 % 리턴) |
x{n,} | n개 이상의 매치가 있는지 확인, "O{2,}"일 경우 "BOY"는 아무 것도 리턴하지 않지만 "GOOOAL"은 모든 O 리턴 |
x|y | 문자열에 x 또는 y가 있는지 확인 |
[^vet] | 부정 집합, 범위에 포함된 값을 제외하고 매치, "veterinary"에서 vet을 제외하고 매치 |
[A-Za-z0-9] | 모든 알파벳과 숫자 확인 |
[a-z] | 모든 소문자 확인 |
[A-Z] | 모든 대문자 확인 |
x(?=y) | 뒤에 y가 올 때만 x 리턴 |
. | 줄 끝을 제외한 모든 단일 문자 확인 |
x* | x가 0개 이상 있는지 확인 |
비밀번호 강도 확인을 위한 정규표현식
다음 규칙에 따라 사용자가 입력하는 비밀번호의 강도를 확인합니다.
- 비밀번호가 최소 8 자리 이상 (?=.{8,))
- 비밀번호에 한개 이상의 대문자 포함 (?=.*[A-Z])
- 비밀번호에 한개 이상의 소문자 포함 (?=.*[a-z])
- 비밀번호에 최소 하나의 숫자 포함 (?=.*[0-9])
- 특수문자 하나 이상 포함 ([^A-Za-z0-9])
비밀번호가 얼마나 안전한지를 나타내는 세 가지 수준이 있습니다.
1. Strong: 비밀번호가 모든 요구 사항을 충족할 때
위의 조건에 따라 최소 하나 이상의 소문자, 하나의 대문자, 하나의 숫자, 하나의 특수문자, 최소 8 자리 입니다.
(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{8,})
2. Medium: 비밀번호 6 자리 이상, 모든 요구 사항을 충족하거나 숫자만 빼고 나머지를 충족하는 경우
코드는 6자리를 체크하기 위해 마지막 (?=.{6,})만 빼고 Strong과 같게 만든 다음 | 을 추가하여 둘 중의 하나의 조건에 매치하도록 합니다.
((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{6,}))|((?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])(?=.{8,}))
3. Weak: 입력한 비밀번호가 strong 이나 medium을 만족하지 못한 경우
HTML 코드
<html>
<head>
<!-- Bootstrap 5 link -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<style>
.displayBadge {
display: none;
text-align: center;
}
</style>
</head>
<body>
<div class="d-flex flex-column align-items-center">
<h4 class="d-flex justify-content-center my-3">
Password Strength Checker
</h4>
<input type="password" placeholder="Type your password" id="PassEntry" class="form-control text-center my-3">
<span id="StrengthDisp" class="badge displayBadge my-3"></span>
</div>
<script src="script.js"></script>
</body>
</html>
- Bootstrap stylesheet의 CDN 경로를 <link> 태크를 통해 HTML 파일에 연결하여 Bootstrap 5를 사용합니다.
- <style> 태그를 통해 커스텀 스타일을 적용할 것 입니다. 비밀번호 강도 표시는 사용자가 비밀번호를 입력했을 때만 표시할 것 이므로 displayBadge 클래스는 숨기도록 하겠습니다.
- <body> 태그에는 <div>와 함께 세 개의 자식 요소를 가집니다.
- 첫 번째 요소는 제목 표시를 위해 간단히 h4를 사용합니다.
- 두 번째 요소는 <input>으로 비밀번호를 입력할 곳 입니다.
- 세 번째 요소는 <span>으로 비밀번호 강도를 표시할 부분입니다. (강력한 경우 초록색, 중간의 경우 파란색, 약한 경우 빨간색)
JavaScript 코드
먼저 다섯 개의 변수를 만듭니다.
- timeout: 콜백이 호출되기 전 timeout id 저장
- password: 입력된 비밀번호 저장
- strengthBadge: 비밀번호의 강도를 표시하는 부분
- strongPassword: strong 정규표현식을 저장
- mediumPassword: medium 정규표현식을 저장
let timeout;
let password = document.getElementById('PassEntry');
let strengthBadge = document.getElementById('StrengthDisp');
let strongPassword = new RegExp('(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{8,})')
let mediumPassword = new RegExp('((?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^A-Za-z0-9])(?=.{6,}))|((?=.*[a-z])(?=.*[A-Z])(?=.*[^A-Za-z0-9])(?=.{8,}))')
정규식을 RegExp.prototype.test() 메소드로 테스트하여 암호의 강도를 확인하는 StrengthChecker라는 함수를 만들어 보겠습니다. 일치하는 항목이 있으면 true를 리턴하고 일치하는 항목이 없으면 false를 리턴합니다.
그 다음 함수의 결과에 따라 뱃지의 배경색(strengthBadge.style.backgroundColor)과 텍스트(strengthBadge.textContent)를 설정합니다.
function StrengthChecker(PasswordParameter) {
if (strongPassword.test(PasswordParameter)) {
strengthBadge.style.backgroundColor = "green"
strengthBadge.textContent = 'Strong'
} else if (mediumPassword.test(PasswordParameter)) {
strengthBadge.style.backgroundColor = 'blue'
strengthBadge.textContent = 'Medium'
} else {
strengthBadge.style.backgroundColor = 'red'
strengthBadge.textContent = 'Weak'
}
}
이벤트 리스너를 비밀번호 input에 추가하고 사용자가 무언가를 입력했을 때 StrengthChecker 함수로 강도를 확인해 보겠습니다. 여기서 키를 누를 때마다 바로 함수를 호출하지 않을 것 입니다. 입력이 있을 때 마다 정규식을 확인하지 않고 사용자가 빠르게 입력하다 멈췄을 때 강도를 체크하기 위해 타임아웃을 설정할 것입니다.
이전 타임아웃이 있으면 취소해야 합니다. 이벤트가 타임아웃 시간보다 더 빨리 발생하면 이전 입력 이벤트의 타임아웃을 취소해야 합니다.
password.addEventListener("input", () => {
strengthBadge.style.display = 'block'
clearTimeout(timeout);
timeout = setTimeout(() => StrengthChecker(password.value), 100);
if (password.value.length !== 0) {
strengthBadge.style.display != 'block'
} else {
strengthBadge.style.display = 'none'
}
});
전체 코드
See the Pen Password Strength Checker by shinyks (@shinyks) on CodePen.
정리
JavaScript의 정규식을 사용하여 3단계 암호 검사기를 만드는 방법을 알아봤습니다. Too Strong 및 Too Weak와 같은 더 많은 레벨을 구현하여 예제를 만들 수 있습니다.
JavaScript의 정규표현식에 대해 더 알고 싶으면 MDN 문서를 확인하기 바랍니다.
관련 글
'dev > javascript' 카테고리의 다른 글
[javascript] 자바스크립트 퍼센트, 백분율 구하기 (4) | 2023.03.24 |
---|---|
[javascript] 자바스크립트 라디안(radians)을 각도(degrees)로 변환 (2) | 2023.03.21 |
[javascript] 자바스크립트 performance.now() (4) | 2023.03.20 |
[javascript] 자바스크립트 지수 연산자(제곱, Math.pow) (2) | 2023.03.20 |
[javascript] 자바스크립트 debounce 함수 지연 시키기 (3) | 2023.03.19 |
댓글