메인 컨텐츠로 가기

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

Perl, jQuery, Ajax, JSON 및 MySQL을 사용한 매우 간단한 로그인

Seda Özses, 공인 IT스페셜리스트 마스터, IBM
Seda Özses
Seda Özses는 마스터 인증 IT 전문가이자 IBM 기업 웹마스터 팀 소속이다. 그녀의 역점 분야는 ibm.com 기업 웹 포털이다. Özses의 이메일 주소는 seda.ozses@at.ibm.com이다.

요약:  매일 수백 개의 도메인이 새로 등록되고 있고 그 수만큼의 웹 사이트가 새롭게 선보이고 있다. 이런 웹 사이트의 대다수는 로그인 기능을 갖춘 웹 애플리케이션을 호스트한다.

이 기사에서는 여러 가지 현대적 기술을 사용하여 구현된 매우 간단한 로그인 기법에 대해 설명한다. 경량의 텍스트 기반 공개 표준(JSON), 크로스 브라우저 JavaScript 라이브러리(jQuery) 및 비동기 대화식 웹 애플리케이션 기술(Ajax)과 함께 스크립팅 언어(Perl), 무료 데이터베이스(MySQL)를 소개한다.

기사 게재일:  2011 년 10 월 11 일
난이도: 중급 원문:  보기
페이지뷰:  2770 회
의견:  


소개

WWW가 세상에 처음 나온 이후로, 개발자들은 다양한 최신 기술을 적용하여 사용자의 관심을 끌고 훨씬 더 쉽게 웹 사이트를 사용할 수 있도록 하기 위해 웹 사이트에 새로운 기능과 위젯을 도입하려는 노력을 멈추지 않고 있다. 요즘의 일반 웹 사용자는 인터넷 상에서 다른 활동 중에서도 특히 쇼핑, 정보 검색, 포럼 및 커뮤니티 등록, 온라인 게임, 다른 사용자와의 통신에 많은 비중을 두고 있다. 이런 활동 중 대부분의 경우 사용자는 일반적으로 웹 사이트에 등록한 후 로그인할 필요가 있다. 따라서 이런 기본적인 기능을 구현할 때 더욱 각별한 주의가 요구된다. 즉, 사용자 입장에서 간단하고 신속하고 안전해야 하는 것이다. 개발자의 관점에서는 새로운 기술 덕분에 이런 기능을 더욱 쉽게 구현할 수 있다.

이 기사에서는 이런 기술들을 몇 가지 이용하여 웹 사이트에 매우 간단하게 로그인할 수 있는 기능을 구현하는 방법을 배울 수 있다.

구현 프로세스를 다음 4가지 섹션으로 나누었다.

  1. SQL 섹션에서는 데이터베이스에 사용자 정보를 저장하기 위한 테이블을 작성하는 방법을 정의한다.
  2. HTML 섹션에서는 로그인 양식뿐 아니라 CSS 및 JavaScript 참조를 구현한다.
  3. JavaScript 섹션에서는 jQuery와 JSON을 사용하여 Ajax 파트를 다룬다.
  4. 마지막으로, Perl 섹션에서는 사용자 입력과 데이터베이스 간의 상호작용에 대해 설명한다.

지시사항 섹션에서는 모든 것을 함께 조합하는 방법에 대한 단계별 지시사항을 확인할 수 있다. 이 기사에서는 독자가 앞서 거론한 기술들에 이미 익숙하고 웹 개발 경험이 있는 것으로 가정하고 설명한다. 이런 기술에 충분한 경험이 있다면 지시사항 섹션으로 바로 건너뛰어도 된다.

본 기사에 포함되지 않은 내용

예를 들어, 사용자가 입력한 데이터가 가능한 데이터인지 여부와 시스템 위협 검사 등과 같은 보안 문제는 본 기사의 주제가 아님을 분명히 밝혀둔다. 그래서 사용자의 비밀번호를 저장하기 위한 암호화 방법도 본 기사의 범위를 벗어나는 내용이다. 하지만, 반드시 시스템에서 발생 가능한 취약점에 대해 알아보고 이런 기능을 코드에 빌드해야 할 것이다.

SQL

매우 간단한 로그인 기술에 대해 다루는 것이므로, users 테이블은 고유 id, 고유 usernamepassword의 3개 필드만으로 구성된다.


리스트 1. SQL 코드
				
CREATE TABLE `mydb`.`users` (
  `id` INT NOT NULL AUTO_INCREMENT ,
  `username` VARCHAR(45) NOT NULL ,
  `password` VARCHAR(45) NOT NULL ,
  PRIMARY KEY (`id`) ,
  UNIQUE INDEX `id_UNIQUE` (`id` ASC) ,
  UNIQUE INDEX `username_UNIQUE` (`username` ASC)
);
COMMIT;

실제 데이터 삽입과 고유성에 대한 유효성 검증은 등록 기능에서 맡게 되므로, 이 두 가지는 본 기사에서 다루지 않는다. users 테이블이 로그인 구현에서 요구될 적절한 사용자 정보로 이미 채워져 있다고 가정한다.

그러나 테스트 목적으로, 다음 코드를 사용하여 users 테이블에 2개의 간단한 항목을 삽입할 수 있다.

INSERT INTO `mydb`.`users` (`id`, `username`, `password`) 
  VALUES(1, 'username1', 'password1');
INSERT INTO `mydb`.`users` (`id`, `username`, `password`) 
  VALUES(2, 'username2', 'password2');
COMMIT;

MySQL을 사용하지 않을 경우에는 데이터베이스의 SQL 구문이 MySQL 구문과 약간 다를 수 있다.


HTML

HTML 파일에는 로그인 양식은 물론이고, CSS 및 JavaScript 파일 참조도 포함된다.

CSS 참조

간소화를 위해, 본 기사에서는 로그인 양식의 디자인보다는 거론된 기술을 구현하는 데 더 중점을 두므로, 크로스 브라우저 호환성도 보장하는 Blueprint CSS 프레임워크라는 수정된 MIT License로 이미 사용 가능한 소스를 사용한다. 물론, 인터넷 상에는 다양한 설계에 사용할 수 있는 훨씬 더 많은 무료 CSS 구현도 공개되어 있다.
Blueprint 프레임워크에 대한 자세한 정보는 참고자료를 참조한다.

<link rel="stylesheet" type="text/css" media="screen, projection" 
  href="http://www.blueprintcss.org/blueprint/screen.css" />
<link rel="stylesheet"  type="text/css" media="screen, projection"
  href="http://www.blueprintcss.org/blueprint/plugins/buttons/screen.css" />
<link rel="stylesheet" type="text/css" media="print" 
  href="http://www.blueprintcss.org/blueprint/print.css" />
<!--[if IE]><link rel="stylesheet" type="text/css" media="screen, projection" 
  href="http://www.blueprintcss.org/blueprint/ie.css"><![endif]-->

JavaScript 참조

jQuery 라이브러리 외에, 기사 후반부에 설명할 JavaScript 파일에 대한 참조도 있다(login.js).

<script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
<script type="text/javascript" src="login.js"></script>

본 기사를 게시하는 시점에서는 jQuery 버전이 1.4.4였으며, 최신 버전을 선택하려면 참고자료를 참조한다.

로그인 양식

로그인 양식은 username 텍스트 필드, password 필드 및 submit 단추로 구성된다.

<form id="loginForm" name="loginForm" method="post" action="">
  <fieldset>
    <legend>Enter information</legend>
    <p>
      <label for="username">Username</label>
      <br />
      <input type="text" id="username" name="username" class="text" size="20" />
    </p>
    <p>
      <label for="password">Password</label>
      <br />
      <input type="password" id="password" name="password" class="text" size="20" />
    </p>
    <p>
      <button type="submit" class="button positive">
       <img alt="ok" src=
       "http://www.blueprintcss.org/blueprint/plugins/buttons/icons/tick.png" /> 
       Login
      </button>
    </p>
  </fieldset>
</form>

입력 데이터를 사람이 입력하거나 컴퓨터에서 생성되는 경우 그 출처를 테스트하기 위해 Captcha를 사용할 수 있다.
Captcha에 대한 자세한 정보는 참고자료를 참조한다.


그림 1. 로그인 양식의 화면 캡처
로그인 양식의 화면 캡처

결과 표시

로그인 조치의 결과는 로드 시간에는 숨겨져 있다가 이후에 JavaScript에 의해 채워지는 div 태그에 표시된다.

<div id="loginResult" style="display:none;">
</div>


그림 2. JavaScript에 의해 리턴되는 오류 메시지의 화면 캡처
JavaScript에 의해 리턴되는 오류 메시지의 화면 캡처

그림 3. Perl 스크립트에 의해 리턴되는 오류 메시지의 화면 캡처
Perl 스크립트에 의해 리턴되는 오류 메시지의 화면 캡처

그림 4. Perl 스크립트에 의해 리턴되는 성공 메시지의 화면 캡처
Perl 스크립트에 의해 리턴되는 성공 메시지의 화면 캡처

완전한 HTML 코드


리스트 2. login.html
				
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Very simple login using Perl, jQuery, Ajax, JSON and MySQL</title>
    <link rel="stylesheet" type="text/css" media="screen, projection" 
      href="http://www.blueprintcss.org/blueprint/screen.css" />
    <link rel="stylesheet"  type="text/css" media="screen, projection"
      href="http://www.blueprintcss.org/blueprint/plugins/buttons/screen.css" />
    <link rel="stylesheet" type="text/css" media="print" 
      href="http://www.blueprintcss.org/blueprint/print.css" />
    <!--[if IE]><link rel="stylesheet" type="text/css" media="screen, projection" 
      href="http://www.blueprintcss.org/blueprint/ie.css"><![endif]-->
    <script type="text/javascript" 
      src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
    <script type="text/javascript" src="login.js"></script>
    <style type="text/css">
      #loginContent { width: 350px; margin: 100px auto; }
      button[type] { margin: 0.5em 0; }
    </style>
  </head>
  <body>
    <div id="loginContent" class="container">
      <div id="loginResult" style="display:none;">
      </div>
      <form id="loginForm" name="loginForm" method="post" action="">
        <fieldset>
          <legend>Enter information</legend>
          <p>
            <label for="username">Username</label>
            <br />
            <input type="text" id="username" name="username" class="text" size="20" />
          </p>
          <p>
            <label for="password">Password</label>
            <br />
            <input type="password" id="password" name="password" class="text" size="20" />
          </p>
          <p>
            <button type="submit" class="button positive">
             <img alt="ok" src=
             "http://www.blueprintcss.org/blueprint/plugins/buttons/icons/tick.png" /> 
             Login
            </button>
          </p>
        </fieldset>
      </form>
    </div>
  </body>
</html>

CSS가 주 관심사는 아니지만, HTML 코드에서 양식과 단추의 모양을 좀 더 괜찮아 보이게 하기 위한 두 가지 추가 인라인 정의가 있다.

코드 유효성 검증

HTML 코드와 추가적인 CSS 정의는 W3C Validation Services에 의해 유효성 검증되었다.
W3C Validation Services에 대한 자세한 정보는 참고자료를 참조한다.


Javascript

사용자가 로그인 양식을 제출하면 jQuery 라이브러리에서 입력 데이터를 읽는다. 빈 필드가 제출되었는지 확인하기 위한 매우 간단한 테스트를 통과한 후, Perl 스크립트에 대해 Ajax 호출이 이루어진다(login.pl). Ajax 호출의 핵심은 dataType 매개변수를 json으로 설정하는 것이다.

스크립트 호출의 결과에 따라, error 또는 success 함수가 호출된다. 이 코드 샘플에서는 두 함수가 모두 loginResult ID를 포함한 div 태그에 결과를 쓴다.

실패한 경우 샘플 코드에는 jQuery에서 제공하는 XMLHttpRequest.responseText, textStatuserrorThrown이 표시된다.

스크립트 호출에 성공한 경우에는 그 응답을 테스트한다. 응답 변수 data에 오류 메시지가 포함되지 않은 경우에는 성공 메시지 외에도 Perl 스크립트에 의해 users 테이블에서 검색되는 사용자의 id가 표시된다. 성공한 경우 코드 샘플은 양식 자체를 숨기고 div 태그만 표시한다.

완전한 JavaScript 코드


리스트 3. login.js
				
$(document).ready(function(){
  $("form#loginForm").submit(function() { // loginForm is submitted
    var username = $('#username').attr('value'); // get username
    var password = $('#password').attr('value'); // get password

    if (username && password) { // values are not empty
      $.ajax({
        type: "GET",
        url: "/cgi-bin/login.pl", // URL of the Perl script
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        // send username and password as parameters to the Perl script
        data: "username=" + username + "&password=" + password,
        // script call was *not* successful
        error: function(XMLHttpRequest, textStatus, errorThrown) { 
          $('div#loginResult').text("responseText: " + XMLHttpRequest.responseText 
            + ", textStatus: " + textStatus 
            + ", errorThrown: " + errorThrown);
          $('div#loginResult').addClass("error");
        }, // error 
        // script call was successful 
        // data contains the JSON values returned by the Perl script 
        success: function(data){
          if (data.error) { // script returned error
            $('div#loginResult').text("data.error: " + data.error);
            $('div#loginResult').addClass("error");
          } // if
          else { // login was successful
            $('form#loginForm').hide();
            $('div#loginResult').text("data.success: " + data.success 
              + ", data.userid: " + data.userid);
            $('div#loginResult').addClass("success");
          } //else
        } // success
      }); // ajax
    } // if
    else {
      $('div#loginResult').text("enter username and password");
      $('div#loginResult').addClass("error");
    } // else
    $('div#loginResult').fadeIn();
    return false;
  });
});


Perl

매우 간단한 구현의 경우 Perl에서는 CGI, DBI 및 DBD::mysql의 3가지 모듈만 필요하다. CGI 모듈의 도움을 받아, Perl 스크립트는 Ajax에서 보낸 usernamepassword 값을 가져온다. 그런 다음, 스크립트는 데이터베이스에 연결하여 주어진 값에 대한 사용자 id를 선택하기 위한 쿼리를 만든다. 쿼리 결과를 바탕으로, 오류 메시지 또는 성공 메시지와 사용자 ID로 JSON 응답이 빌드된다. Perl 스크립트는 컨텐츠 유형을 application/json으로 설정하고 jQuery에 의해 data 변수에 캐치되는 JSON 문자열로 Ajax에 응답한다.

완전한 Perl 코드


리스트 4. login.pl
				
#!/usr/bin/perl -T
use CGI;
use DBI;
use strict;
use warnings;

# read the CGI params
my $cgi = CGI->new;
my $username = $cgi->param("username");
my $password = $cgi->param("password");

# connect to the database
my $dbh = DBI->connect("DBI:mysql:database=mydb;host=localhost;port=2009",  
  "mydbusername", "mydbpassword") 
  or die $DBI::errstr;

# check the username and password in the database
my $statement = qq{SELECT id FROM users WHERE username=? and password=?};
my $sth = $dbh->prepare($statement)
  or die $dbh->errstr;
$sth->execute($username, $password)
  or die $sth->errstr;
my ($userID) = $sth->fetchrow_array;

# create a JSON string according to the database result
my $json = ($userID) ? 
  qq{{"success" : "login is successful", "userid" : "$userID"}} : 
  qq{{"error" : "username or password is wrong"}};

# return JSON string
print $cgi->header(-type => "application/json", -charset => "utf-8");
print $json;

코드 유효성 검증

유효한 JSON 응답을 빌드하기 위해, JSON 유효성 검증기를 사용하고 싶을 수도 있을 것이다.
JSON 유효성 검증에 대한 자세한 정보는 참고자료를 참조한다.

생성된 JSON 문자열 표시

브라우저에서 JSON 문자열을 확인할 수 있다.

  1. $cgi->header(-type => "application/json", -charset => "utf-8");print $cgi->header;로 변경한다.
  2. 브라우저에 http://your-domain-name_or_localhost/cgi-bin/login.pl?username=username1&password=password1을 입력한다.

그림 5. JSON 문자열의 화면 캡처
JSON 문자열의 화면 캡처

지시사항

  1. SQL 코드users 테이블을 작성하고(mydb를 적당한 값으로 변경), 테이블을 테스트 데이터로 채운다.
  2. login.htmllogin.js를 복사하여 웹 서버의 htdocs 폴더에 붙여넣는다. 폴더 이름은 웹 서버의 설정에 따라 달라질 수 있다.
  3. login.pl을 복사하여 웹 서버의 cgi-bin 폴더에 붙여넣는다. 폴더 이름은 웹 서버의 설정에 따라 달라질 수 있다.
  4. 버전에 따라 Perl 스크립트의 첫 행을 변경하고(일반적으로 Unix의 경우 #!/usr/bin/perl, Windows의 경우 #!\Perl\bin\perl.exe), mydb, localhost, 2009, mydbusernamemydbpassword도 알맞은 값으로 변경한다.
  5. 브라우저에 http://your-domain-name_or_localhost/login.html을 입력한다.
  6. 올바른 값뿐 아니라 잘못된 값도 사용자 이름과 비밀번호로 입력하여 다양한 결과를 확인한다.

중요

HTML, JavaScript 및 Perl 파일이 동일한 도메인에 호스트되어 있는지 확인한다. 그렇지 않은 경우 Ajax가 동일한 도메인에 호출 스크립트로 호스트되어 있지 않은 Perl 스크립트를 호출하려 할 때 동일 출처 정책을 위반하게 되는 것이므로, 오류가 발생한다(data 변수가 null임). 더욱이, 똑같은 이유로 웹 서버에서 HTML 파일을 사용해야 한다.
동일 출처 정책에 대한 자세한 정보는 참고자료를 참조한다.


결론

본 기사를 쓴 취지는 로그인 서비스를 구현하기 위한 훌륭한 시작점으로 사용할 수 있도록 현대적 기술을 적용한 정말 간단한 코드를 제시하는 것이다. 이렇듯 간단한 코드에 보안을 포함한 다양한 기능을 고안하여 빌드할 수 있다. 아이디어가 떠오른 후 다른 데이터베이스 및 프로그래밍 언어를 사용하고 싶을지도 모르겠다.


참고자료

필자소개

Seda Özses

Seda Özses는 마스터 인증 IT 전문가이자 IBM 기업 웹마스터 팀 소속이다. 그녀의 역점 분야는 ibm.com 기업 웹 포털이다. Özses의 이메일 주소는 seda.ozses@at.ibm.com이다.

잘못된 도움말 신고

부정사용 신고

감사합니다. 이 항목은 운영자가 관심을 표시했습니다.


잘못된 도움말 신고

부정사용 신고

제출실패 신고. 나중에 다시 실행해주세요.


디벨로퍼웍스 로그인


IBM ID가 필요하세요?
IBM ID를 잊으셨습니까?


비밀번호를 잊으셨습니까?
비밀번호 변경

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

화면상에 보여지는 닉네임을 정하세요.

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

3개의 &이나 대쉬를 포함해주시고 31글자내로 제한해주세요.


developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


아티클 순위

의견

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=20
Zone=SOA와 웹서비스, 웹 개발
ArticleID=764327
ArticleTitle=Perl, jQuery, Ajax, JSON 및 MySQL을 사용한 매우 간단한 로그인
publish-date=10112011

태그

Help
검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오.

태그를 더 많이 보거나 적게 보기 위해 슬라이더 막대를 사용하십시오.

인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다.

내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.

검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오. 인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다. 내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.