https://okayoon.tistory.com/entry/fingerprintjs-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80-%EC%A7%80%EB%AC%B8

 

Fingerprint.js란?__브라우저 지문 라이브러리__보안

Fingerprint.js 라이브러리 https://github.com/Valve/fingerprintjs 사용자의 브라우저 버전을 표시할 수 있다. - 웹 서버가 통신을 하는 과정에서 전송되는 기본정보 - 브라우저의 종류 - PC의 운영체제(OS) -..

okayoon.tistory.com

fingerPrint.js는 더 이상 관리하지 않는다고 한다. 
버전 2를 사용하도록 한다!
그리고 ie8 이하 지원하지 않아서 분기해서 js자체를 로드 안시키거나 하는등의 예외처리해야한다.
<script type="text/javascript" src="/public/javascripts/jquery.min.js"></script>

// 브라우저 분기
<!--[if !IE ]> -->
<script type="text/javascript" src="/public/javascripts/lib/fingerprint2.js"></script>
<!-- <![endif]-->
<!--[if gt IE 8]>
<script type="text/javascript" src="/public/javascripts/lib/fingerprint2.js"></script>
<![endif]-->

<script>
  // fingerprint2.js
  (function() {
    var $input = $('#fingerPrintKey');
    if($input.length < 1) return false;

    // 브라우저 분기2 (ie8 이하일때 지원 불가 예외 처리...)
    (브라우저 ie이면) ? $input.parent().hide() : getFingerPrintCode();

    function getFingerPrintCode(){
      var fingerPrint = new Fingerprint2();
      
      fingerPrint.get(function (code) {
      	$input.val(code);
      })
    }
  })();
</script>
new Fingerprint2(); 해서 get할때까지 딜레이가 좀 있었다.
그래서 그냥 브라우저 로드하면 키값 넣은 후에 submit 시킬때 파라미터로 넘길지 안넘길지로 작업했다.
암호화해서 자동로그인 시킬때 추가적인 부분에 사용했다.

 

 

+ 이슈 추가

IE11에서 듀얼모니터일 경우 2번 모니터로 볼 경우 주 모니터(1번 모니터)의 값만 받아오는 현상.

 

fringerprint2.js에서 해상도를 어떻게 가져오는지를 먼저 파악하기위해 js파일의 라인428에 있는 getScreenResolution 메서드를 확인해봤는데, window.screen을 통해 모니터의 해상도를 구하고 있었다.

이것을 토대로 검색을 해본 결과 IE11 브라우저 버그인 것 같다.

IE11에서는 주 모니터의 옵션만 가져오는 것으로 보인다.

window.screen 테스트

 

크롬, 엣지

1번 모니터

2번 모니터

각각 다른 widtn, height값을 확인할 수 있다.

 

IE11

1번 모니터

2번 모니터

동일한 값을 확인할 수 있고, 이 값이 주모니터의 값이란 것을 확인할 수 있다.

 

 

 

요구사항
  1. 숫자 전각을 반각으로 인식

 

문제점
  1. 일본어는 전각, 반각이 있다.

  2. 반각은 1byte, 전각은 2byte

  3. byte체크하는 함수를 만들었을 때.. 오류가 발생!

 

JS

- 전각 숫자를 반각 숫자로 변경
String.prototype.toHalfWidth = function(){
    return this.replace(/[!-~]/g, function(r){ // replace의 정규식은 요구사항에 맞추어 변경가능
        return String.fromCharCode(r.charCodeAt(0) - 0xFEE0);
    });
};

var result = '000'.toHalfWidth();
console.log(result); // 000

- 숫자외에 입력 불가
result = result.replace(/\s|\D/g, '');

- 4자리씩 끊어서 한칸 띄고 작성
result = result.replace(/(\d{4})\B/g, '$1 ');

//여기서 $1은 첫번째 괄호값이라고 한다($1~$9까지 9개를 저장할 수 있다고)
// MSDN 참조 링크 : https://msdn.microsoft.com/ko-kr/library/24th3sah(v=vs.94).aspx
// 정규표현식 테스트 사이트 https://regexr.com/​
 
의문점
일본어는... 엔터치면 반각이 되고... 스페이스 치면 전각이 되는 거지? 이해불가....

 


 

전각 반각 테스트 방법

 
Windows 8.1 기준

 

 

화면 왼쪽 하단 윈도우 아이콘 마우스 우 클릭해서 제어판 오픈

 

or

 

윈도우키 + R 누르면 실행창 뜨는데, 거기서 control 입력 후 확인 눌러도 제어판 오픈 됨.

 

 

 

 

보기 기준 '범주' 에서 

시계, 언어 및 국가별 옵션 > 언어 추가

 

 

언어 추가 클릭

 

 

언어 추가 창에서 오른쪽 상단에 추가 언어 검색

'일본어' 입력 하면 추가 화면에 뜨는 것 확인 가능.

 

추가

 

 

추가하면 확인 가능한게 2가지있음.

첫번째는 언어 기본 설정 변경에 추가 된 언어가 보임

두번째는 오른쪽 하단에 시계 옆 쪽으로 Microsoft 입력기가 생김.

 

 


 

전각/반각 설정법

 

 

확대하면 이렇게!

마우스 클릭 또는 Windows키+space키 하면 언어 전환 가능

 

 

그 옆 'A'로 뜨거나 '가'로 뜨거나... 전환키가 뜨는데

여기서 전각/ 반각 확인 가능함.

한글일땐 전/반자 이라 써있고 일본어 일땐 저렇게 나타나는데 Full-width가 전각임

 

 

구글창에서 확인해보면 

앞쪽에 얇아보이는 글이 반각이고

하단에 밑줄있는게 전각임.

 

 

+(Windows 10에서 하는 방법)

 

 

윈도우 아이콘 클릭 후 설정 클릭(톱니바퀴 아이콘)

 

 

windows 설정에서 시간 및 언어 클릭

 

 

언어 영역이 보이면

 

 

언어 추가 클릭

 

 

설치할 언어 검색 후 클릭 > 다음

 

 

해당 언어 기능 옵션 선택 후 설치

(예시 : 음성 체크 -> 음성도 같이 설치)

 

 

 

화살표로 순서 변경 가능, 제거 가능.

다시 시작하면 됨.

 

그 다음엔 위에 전각/반각 설정법 참고

 

 

 

Fingerprint.js 라이브러리

https://github.com/Valve/fingerprintjs

 

사용자의 브라우저 버전을 표시할 수 있다.

- 웹 서버가 통신을 하는 과정에서 전송되는 기본정보

- 브라우저의 종류

- PC의 운영체제(OS)

- 쿠키 사용여부(브라우저 설정값) 정보

- 어도비 플래시(Adobe Flash), 자바 가상머신(Java Virtual Machine)을 통해 브라우저 기능을 지원하는 프로그램의 버전

- PC의 표준시

- 화면 해상도

- PC의 보유 글꼴 및 색상 등의 정보

- 그 외에도 여러가지.

 

이러한 정보들을 모아서 브라우저 지문이라고한다.

 

개인을 식별 할 수 있는 정보이기보다는 접속한 pc, 브라우저의 단순한 설정 정보를 말한다.

다양한 값을 가지기 때문에 로그인 시에 '2단계 인증'의 로직 중에 하나로 사용될 수 있다.

 

설정값 같은 경우에는 사용자 설정에 따라 수집된다.

예를 들어 pc의 표준시를 수집하는 경우 해당 pc의 국가나 사용자의 설정에 따라 24가지(-12~+12)의 값을 가질 수 있다.

 

쿠키는 보안설정 등의 변경으로 사용을 차단할 수 있지만, 브라우저 지문은 쿠키차단, IP주소를 숨기는 프록시를 사용하더라도 정보를 수집할 수 있다.

변경하려면 운영체제 및 소프트웨어의 정보를 변경해야 한다고한다.

 

특징을 잘 활용하면 쿠키 없이도 사용자를 식별할 수 있는 정보로 사용될 수 있다.



form validation

 

HTML

<div class="wrap">
    <form id="step-verification" class="form" active="" method="post">
        <div class="box">
            <h1 class="title">인증 절차</h1>
            <p class="desc">
              안전한 계정 사용을 위해 인증을 사용해 주세요.<br>
              인증은 아이디와 비밀번호 외 일회용 인증번호를 입력해야만
              로그인 할 수 있는 이중 보안 서비스입니다.<br>
              인증에 필요한 이메일을 등록하고 더욱 안전하게 계정을 보호하세요.
            </p>
            <p class="agree-area">
              <input id="agree" type="checkbox" />
              <label for="agree">
                인증을 위해 개인정보 수집 및 이용에 동의합니다.(필수)
              </label>              
          </p>
        </div>
        <div class="box">
          <h2 class="title">이메일 등록</h2>
          <p class="desc">        
            인증이 가능한 이메일 주소를 입력 후 인증번호 받기를 선택해 주세요.<br>
            입력한 이메일 주소로 발송된 인증번호를 입력하고 확인을 선택해 주세요.
          </p>
          <div class="email-area">
            <p>
              <label for="email">이메일</label>
              <input id="email" type="email" placeholder="이메일을 입력해주세요." />
              <button id="send-access-code" type="button">인증번호 받기</button>
            </p>
            <p>
              <label for="email-code">인증번호</label>
              <input id="email-code" type="text" placeholder="인증번호 입력(20분 이내)" />
            </p>
          </div>
        </div>
        <div>
          <button id="prev-page" type="button">이전으로</button>
          <button id="submit" type="button">확인</button>
        </div>
    </form>
</div>

 

 

 

 

CSS

.wrap{
  margin:0 auto;
  width:900px;
  background-color:#fff;
  border:1px solid #c4c4c4;
  box-shadow:3px 3px 10px rgba(0,0,0,0.3);
  font-size:16px; line-height:22px;
  color:#333;
}
.form{
  padding:30px;
}
.title{
  padding-bottom:20px; border-bottom:1px solid #c4c4c4;
}
.email-area label{
  display:block;
}
input[type=text],input[type=email]{
  width:50%; height:30px; text-indent:10px;
}
button{
  display:inline-block;
  height:35px;
  background-color:#fff;
  border:1px solid #c4c4c4; box-sizing:border-box;
}
button:hover{ background-color:#c4c4c4; color:#fff; }
.error-msg{ margin:0; color:red; font-size:12px; }

 

 

 

 

JS

var reg = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

// 이전으로 버튼
$('#prev-page').on('click', function(){ history.go(-1) });

// 유효성 검사
$('#send-access-code').on('click', function(){
  var $sendButton = $(this);
  var target = $(this).siblings('input[type=email]');
  accessCodeEmailValidate($sendButton,target);
});

$('#submit').on('click', function(){
  var $form = $('#step-verification');
  var validationResult = twoStepVaildate($form);
  
  if(validationResult){
    alert('성공!');
    // $form.submit();
  }
});

function accessCodeEmailValidate(triggerBtn,target){
  var $target = $(target);
  var targetVal = $(target).val();
  
  if(targetVal == ''){
    var errorMsg = '이메일 주소를 입력해주세요.';
    setErrorMsg($target,errorMsg);
    // alert('이메일 주소를 입력해주세요.');
    
  }else if( !reg.test(targetVal.toLowerCase()) ){
    var errorMsg = '잘못된 이메일 입니다.';
    setErrorMsg($target,errorMsg);
    
  }else{
    // api 호출 성공 시 btn 이름 변경
    $(k).siblings('#error').hide();
    if( $(triggerBtn).val() !== 'resend' ) $(triggerBtn).val('resend').text('인증번호 재발송');
  }
}

function setErrorMsg(target,errorMsg){
  var $target = $(target);
  var $targetParent = $target.parent();
  
  if($targetParent.find('#error').length < 1){
  	$targetParent.append('<p id="error" class="error-msg">'+ errorMsg +'</p>');
    
  }else{
  	$targetParent.find('#error').text(errorMsg).show();
  }
}

function twoStepVaildate(form){
  var validTarget = $(form).find('input');
  var failNum = 0;

  $.each(validTarget, function(i,k){
    // 개인 정보 동의
    if(k.type == 'checkbox') {
      var result = k.checked == true ? true : false;

      if (!result) {
        alert('2단계 인증 설정을 위한 개인정보 수집 및 이용에 동의해주세요.');
        failNum = failNum + 1;
      }
    }else if(k.type == 'text'){
      if(k.value == '') {
        failNum = failNum + 1;

        // error
        var errorMsg = '인증번호를 입력해 주세요.';
        setErrorMsg(k,errorMsg);

      }else{
          $(k).siblings('#error').hide();
      }

    }else if(k.type == 'email'){
      if(k.value == '') {
        failNum = failNum + 1;

        // error
        var errorMsg = '이메일 주소를 입력해주세요.';
        setErrorMsg(k,errorMsg);
      }else{
        if( !reg.test(k.value.toLowerCase()) ){
          failNum = failNum + 1;
          var errorMsg = '잘못된 이메일 입니다.';
          setErrorMsg(k,errorMsg);

        // error
        }else{
            $(k).siblings('#error').hide();
        }
      }
    }
  });

  if(failNum > 0) return false;
  else return true;
}

 

 

+ Recent posts