[Android Studio] 안드로이드에서 로그인 기능 구현하기 [3]

     

안녕하세요? 지난번 포스팅에서는 아래와 같은 기능을 다루었습니다.



1. 서버와 클라이언트 사이의 통신. 리턴값 셋팅하기

2. 아이디와 비밀번호를 이용해 로그인 하기

3. 회원가입시 이메일 보내기

지난번 포스팅 바로가기


이번 포스팅에서는 아래와 같은 기능을 다루어 보겠습니다.



1. 메일 인증된 사용자만 로그인 가능하게 하기

2. 비밀번호 5회 오류 시 로그인 막기


사실 이런 기능들은 실제 서비스 레벨에서 꼭 필요한 기능들이지만, 여기서는 적용해야 할지 안해야할지 고민했던 기능들입니다. 하지만 많이 사용하는 기능들이기 때문에 한번 만들어보는 것이 좋다고 생각해요 ~


일단 시작하기 전에 지난 포스팅에서 이메일을 보내서 인증하는 기능을 추가했는데, 이메일관련 로그때문에 회원가입에 성공했지만 성공이 아니라는 에러 팝업이 뜨는걸 확인했습니다. 이부분을 먼저 수정하고 넘어갈께요~



위 스크린샷에서 볼 수 있듯이 정상처리를 표시하는 '0'값 뒤에 SMTP(이메일 프로토콜)로 시작하는 많은 로그들을 확인할 수 있습니다. (물론 팝업창에서 나오더라구요..) 아무튼 이 로그들이 찍히지 않게 하기위해 지난 포스팅에서 소개한 Sendmail.php 소스를 수정할 필요가 있습니다. 로그찍는 곳을 다 수정해야하나.. 생각했는데 Debug모드를 설정할 수 있도록 만들어져 있어서 쉽게 수정할 수 있더라구요.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
/* 
=================================================================================
 + 안내 : 이 파일은 아래의 웹싸이트 자료를 참고로 수정하였음을 알려드립니다.
 + 출처 : http://redqueen-textcube.blogspot.kr/2011/07/php-class.html
 + 제작자 : 하근호(hopegiver@korea.com)
=================================================================================
 + 파일명 : Sendmail.php
 + 수정일 : 2015-06-04/2015-06-04(최종수정일)
 + 수정자 : Redinfo (webmaster@redinfo.co.kr)
 + 기타   : (가이드 URL) http://b.redinfo.co.kr/87
            (싸이트 URL) http://b.redinfo.co.kr
=================================================================================
*/
 
class Sendmail {
    /* smtp 의 호스트 설정 : 아래는 gmail 일경우 */
    var $host="ssl://smtp.gmail.com";
    /* smtp 계정 아이디 입력 */
    var $smtp_id="@gmail.com";
    /* smtp 계정 비밀번호 입력 */
    var $smtp_pw="";
    
    /* 디버그모드 - 활성 :1, 비활성 : 0; */
    var $debug = 0
    /* 문자 인코딩 종류 설정*/
    var $charset="UTF-8";
    /* 메일의 기본 타입을 설정 */
    var $ctype="text/plain";
cs


위 코드에서 25번째 줄을 보시면 debug변수를 1과 0으로 설정할 수 있는데, 0으로 설정하면 로그가 찍히지 않습니다.


 1. 메일 인증된 사용자만 로그인 가능하게 하기


 지난 포스팅에서 이메일로 사용자를 인증하는 기능을 만들었는데, 인증을 하지만 로그인할 때 체크하지 않는다면 만드는 의미가 없겠죠? 인증된 사용자만 로그인을 시켜주기 위해서 로그인하는 소스를 조금 손봅니다. 맨처음 사용자 ID를 관리하는 USER테이블을 만들 때, VERIFY테이블을 이용해 ID가 인증되었는지 안되었는지 체크할 수 있게 설계했습니다. 물론 지난 포스팅에서도 메일로 전송된 주소를 클릭하면 VERIFY값을 UPDATE하다록 만들었구요. 따라서 로그인 할때 VERIFY값이 Y인지 체크하고, N값일 경우 에러를 내뱉으면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
// 비밀번호 비교
  $sql = "SELECT IF(strcmp(PASSWORD,'$pw'),0,1) pw_chk, VERIFY FROM USERS  WHERE USERID = '$id'";
 
  $result = mysql_query($sql);
 
  // 쿼리 결과
  if($result)
  {
    $row = mysql_fetch_array($result);
    if(is_null($row[pw_chk]))
    {
      echo "Can not find ID";
    }
    elseif($row[VERIFY] == 'N')
    {
      echo "Unverified ID";  // 인증받지 않음
    }
    else
    {
      echo "$row[pw_chk]";   // 0이면 비밀번호 불일치, 1이면 일치
    }
  }
  else
  {
   echo mysql_errno($connect);
  }
cs


위와같이 쿼리문에서 VERIFY컬럼도 조회하도록 수정합니다. 쿼리결과를 처리하는 곳에서는 VERIFY값이 N일경우 'Unverified ID"라는 메시지를 리턴합니다. 이렇게 되면 만약 ID가 인증받지 않아 VERIFY값이 N일 경우에 에러를 리턴하겠죠?

실제로 인증하지 않은 ID로 로그인 해봅시다.



이렇게 나오면 성공~!


 2. 비밀번호 5회 오류 시 로그인 막기


 비밀번호 5회 오류는 사이트마다 정책이 달라서 적용하는 곳도 있고, 적용하지 않는 곳도 있습니다. 어떤 곳은 10회오류를 체크하기도 합니다. 보통 금융권들은 5회오류라서 5회오류로 만들어보겠습니다. 


 비밀번호 오류는 서버에서 체크해야 여러 채널에서 접속해도 동일한 오류 횟수를 내보내줄 수 있습니다. 즉, 클라이언트에서 체크하면 안된다는 거지요. 당연한 말이지만 ..^^ 하지만 현재 저희가 사용하는 공인인증서같은경우 클라이언트에서 비밀번호를 체크하기 때문에 PC에서 오류난 횟수와 모바일에 옮긴 인증서의 비밀번호 오류 횟수가 동기화가 안됩니다. 정말 이상한 시스템이 아닐 수 없지만, 인증서를 관리하는 회사와 인증서로 인증을 받고 서비스를 제공하는 회사가 다르기 때문에 어쩔 수 없는 구조이지요. 


 오류횟수를 체크하기 위해 USER 테이블에 FAIL_CNT라는 오류횟수를 체크하는 컬럼을 추가합니다.


아무래도 횟수이기 때문에 Int로 만들어 보았습니다. 이제 로그인할 때 비밀번호가 틀릴경우, 이 FAIL_CNT를 1씩 증가시켜 봅시다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
  // 쿼리 결과
  if($result)
  {
    $row = mysql_fetch_array($result);
    if(is_null($row[pw_chk]))
    {
      echo "Can not find ID";
    }
    elseif($row[VERIFY] == 'N')
    {
      echo "Unverified ID";  // 인증받지 않음
    }
    elseif($row[pw_chk] == 0)
    {
      echo "Password error"
      $sql = "UPDATE USERS SET FAIL_CNT = FAIL_CNT + 1 WHERE USERID = '$id'"
      mysql_query($sql)
    }
    else{
      echo "$row[pw_chk]";   // 0이면 비밀번호 불일치, 1이면 일치  
    }
cs


14번째 줄을 보면 비밀번호가 불일치할 경우 해당 ID의 FAIL_CNT를 1 증가시키는걸 볼 수 있습니다. 에러메시지는 Password error라고 셋팅했습니다. 자 이제 비밀번호가 틀릴때마다 FAIL_CNT가 1씩 증가하겠지용?


이제 이 CNT가 5가 됬을때, 로그인을 막는걸 만들어야합니다. 어떻게 하면 될까요? 틀릴때마다 1씩 증가하기 때문에 로그인을 할때 ID정보를 가져오는 순간의 FAIL_CNT값도 같이 가져와서 5회인지 체크하고, 5회가 넘으면 에러를 출력하면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
// 비밀번호 비교
  $sql = "SELECT IF(strcmp(PASSWORD,'$pw'),0,1) pw_chk, VERIFY, FAIL_CNT FROM USERS  WHERE USERID = '$id'";
 
  $result = mysql_query($sql);
 
  // 쿼리 결과
  if($result)
  {
    $row = mysql_fetch_array($result);
    if(is_null($row[pw_chk]))
    {
      echo "Can not find ID";
    }
    elseif($row[FAIL_CNT] >= 5)
    {
      echo "Password error 5"
    }
    elseif($row[VERIFY] == 'N')
    {
      echo "Unverified ID";  // 인증받지 않음
    }
    elseif($row[pw_chk] == 0)
    {
      echo "Password error"
      $sql = "UPDATE USERS SET FAIL_CNT = FAIL_CNT + 1 WHERE USERID = '$id'"
      mysql_query($sql)
    }
    else{
      echo "$row[pw_chk]";   // 0이면 비밀번호 불일치, 1이면 일치  
    }
    
  }
  else
  {
   echo mysql_errno($connect);
  }
cs


위처럼 쿼리에 FAIL_CNT 컬럼을 추가하고, 이 컬럼의 값이 5가 넘으면 에러를 리턴합니다. 초기에 만들었던 로그인은 참 간단했는데 점점 if문이 복잡해지죠? 실제로 회사에서 쓰는 쏘스들중에 로그인이 제일 더러울겁니다...(예외처리가 많기때문에)




이제 5회 오류와 인증받은 사용자만 로그인할 수 있도록 Login소스 수정이 끝났습니다. 하지만 실제로 서비스할 수 있는 수준까지 가려면 더 많은 기능들이 추가되어야 합니다.

일단 5회 오류시 사용자 인증을 받고 초기화하는 기능이 필요할 것같은데요. 이 기능은 지난 회에서 다루었던 이메일 인증과 비슷한 방식으로 진행하면 될 것같습니다. 메일을 보내서 링크를 클릭할 경우 clear.php를 만들어서 해당 ID의 FAIL_CNT를 0으로 업데이트하는 겁니다. 이것말고도 여러가지 방법으로 만들 수 있으니 직접 해보시는게 좋을 것같습니다.


로그인 관련된 예외처리는 상당~~~히 많지만 기본적인 회원가입과 로그인관련 포스팅은 이것으로 마무리를 하도록 하겠습니다. 대부분의 추가 기능들은 여태까지 해온 것들을 조금씩 수정해보시면 만들 수 있을거라고 생각합니다.ㅎㅎ (절대 귀찮아진거 아님) 화이팅~


반응형

댓글

Designed by JB FACTORY