웹 게시판 생성 실습

웹서버 오라클서버 연동하여 웹 게시판 생성 실습

이전 실습에서 이어서 진행한다.

 

오라클 서버 및 WEB 서버 설치

오라클을 설치하고 설치된 오라클에 web 서버가 연동이 되도록 설정 ◾ 조건 • 오라클 서버 구축후 새로운 계정은 생성하지 않는다.  - 연동 test는 예제 스키마인 HR을 이용한다.  - web 서버

lemonandgrapefruit.tistory.com

 

실습

1. 웹서버 오라클서버 연동 확인

 

2. 게시판 구현을 위한 데이터 요구

 1) 게시판 외부스키마

 2) 게시판 논리적 모델링

 3) 게시판 물리적모델링

 4) 게시판 테이블 생성

 

3. 게시판 구현

 1) board table space 생성 및 board user 생성

 2) 오라클 접속 및 board 테이블 생성

 3) 게시판 구현

 

4. 웹서버에 디렉토리 업로드

 

5. 보안 구현

 1) PW 저장된 해시값 다르게 설정한 사용자 인증 구현

 2) 로그인하지 않으면 파일 접근 불가능 구현

 3) SQL Injection 예방 구현

 4) 게시글 작성자만 게시글 삭제 가능 구현


1. 웹서버 오라클서버 연동 확인

오라클 서버: 192.168.11.136

웹서버: 192.168.11.137

 

웹서버와 오라클서버 연동을 확인한다.

/home/httpd/index.html 파일은 아래와 같다.

<html>
<head>
<title> st04 </title>
<meta charset="UTF-8">
</head>
<body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
<p>&nbsp;</p>
<table border="1" align="center">
<tr>
<td width="100">
<p align="center">목록<br></p>
<p align="center"><a href="html">html</a><br></p>
</td>
</tr>
</table>
</html>
<?
$server = "ora";
$user_name = "hr";
$password = "hr";
$conn=@oci_connect($user_name,$password,$server) or die('not connect:');
echo("Oracle 19c \$conn : $conn<br>");
$st=oci_server_version($conn);
echo("$st<br>");
phpinfo();
?>

 

오라클이 연동된 것을 확인할 수 있다.

 

2. 게시판 구현을 위한 데이터 요구

1) 게시판 외부스키마

- view (게시판목록)

: id(사용자계정), pw(계정비밀번호), 게시물번호, 게시물제목, 별명, 게시물작성일시, 게시물조회수

 

- id (회원가입)

: id(사용자계정), pw(계정비밀번호), | (추가항목) 별명, 주민번호, 메일주소, 전화번호

 

- content (게시물 내용)

: 게시물제목, 별명, 게시물작성일시, 게시물내용

 

2) 게시판 논리적 모델링

- 사용자(id) Table

: id, pw, 별명(name), 주민번호(jumin), 메일주소(email), 전화(tel)

 

- 게시판(board) Table

: 게시물번호(bno), 게시물제목(subject), 게시물내용(content), 게시물작성일시(bdate),

게시물작성자(id.name), 조회수(hit)

3) 게시판 물리적모델링

주민번호 같은 민감한 개인정보는 해시값으로 저장한다.

 

4) 게시판 테이블 생성

물리적 모델링을 참조하여 게시판 생성 sql문을 작성한다.

createboard.sql

createboard.sql
0.00MB

DROP TABLE board;
DROP TABLE id;
PURGE RECYCLEBIN;


DROP sequence board_bno_seq;


CREATE TABLE id(
id VARCHAR2(15),
pw VARCHAR2(40),
name VARCHAR2(100) NOT NULL,
jumin VARCHAR2(48),
email VARCHAR2(100),
tel VARCHAR2(20)
);


CREATE TABLE board(
bno NUMBER,
id VARCHAR2(15),
subject VARCHAR2(200),
bdate DATE,
hit NUMBER,
content VARCHAR2(4000)
);




ALTER TABLE id
ADD CONSTRAINT id_pk_id PRIMARY KEY (id);
ALTER TABLE board
ADD CONSTRAINT board_pk_bno PRIMARY KEY (bno);


ALTER TABLE board
ADD CONSTRAINT board_fk_id FOREIGN KEY (id)
REFERENCES id (id);


CREATE SEQUENCE board_bno_seq;

 

 

3. 게시판 구현

1) board table space 생성 및 board user 생성

192.168.11.136 오라클 서버에서 진행한다.

 

board table space를 생성할 것이다.

분산저장하기 위해 /app/ora19c/oradata/disk1, /app/ora19c/oradata/disk2를 생성한다.

board table space를 생성한다.

SQL> !ls /app/ora19c/oradata/
DB19


SQL> !mkdir /app/ora19c/oradata/disk1


SQL> !mkdir /app/ora19c/oradata/disk2


SQL> !ls /app/ora19c/oradata/
DB19 disk1 disk2


SQL> CREATE TABLESPACE board
2 DATAFILE
3 '/app/ora19c/oradata/disk1/board01.dbf' SIZE 100M,
4 '/app/ora19c/oradata/disk2/board02.dbf' SIZE 100M;


Tablespace created.

 

게시판 연동에 사용되는 테이블등의 개체는 모두 board 스키마에 생성한다.

board 사용자를 생성하고 권한을 부여한다.

SQL> CREATE USER board
2 IDENTIFIED BY board
3 DEFAULT TABLESPACE board
4 QUOTA UNLIMITED ON board;


User created.


SQL> GRANT connect, resource TO board;


Grant succeeded.


SQL> GRANT execute on DBMS_CRYPTO TO resource;


Grant succeeded.

 

2) 오라클 접속 및 board 테이블 생성

데이터베이스에 board에 대한 테이블을 생성하기 전에 board 계정으로 오라클 접속할 것이다.

이미 리스너는 구동되어있는 상태이다.

192.168.10.130 윈도우 컴퓨터의 tnsnames.ora 파일을 확인한다.

tnsnames.ora 파일에 192.168.11.136 오라클 서버 ip 주소가 있는지 확인한다.

oracle =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.11.135)(port = 1521))
(CONNECT_DATA = (SID = DB19))
)


ora =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.11.136)(port = 1521))
(CONNECT_DATA = (SID = DB19))
)


dal =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = tcp)(HOST = 192.168.10.11)(port = 1521))
(CONNECT_DATA = (SID = DB19))
)

 

데이터베이스에 board에 대한 테이블을 생성하기 전에 192.168.10.130 컴퓨터에서 리스너 구동 확인과 board 테이블을 생성하는 sql 파일(createboard.sql)을 올릴 것이다.

접속 계정은 board이다.

createboard.sql이 잘 실행된 것을 확인할 수 있다.

C:\Users\st04>cd sql


C:\Users\st04\sql>sqlplus board/board@ora


SQL*Plus: Release 19.0.0.0.0 - Production on 금 1월 7 14:09:35 2022
Version 19.3.0.0.0


Copyright (c) 1982, 2019, Oracle. All rights reserved.


마지막 성공한 로그인 시간: 금 1월 07 2022 22:57:44 +09:00


다음에 접속됨:
Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production
Version 19.3.0.0.0


SQL> @createboard


테이블이 삭제되었습니다.


테이블이 삭제되었습니다.


휴지통이 지워졌습니다.


시퀀스가 삭제되었습니다.


테이블이 생성되었습니다.


테이블이 생성되었습니다.


테이블이 변경되었습니다.


테이블이 변경되었습니다.


테이블이 변경되었습니다.


시퀀스가 생성되었습니다.

 

3) 게시판 구현

board로 오라클을 접속해 로그인한다.

게시판 연동에 사용되는 스키마는 board를 사용한다.

conn.php

<?
$oserver = "ora";
$oname = "board";
$opassword = "board";
$conn=@oci_connect($oname, $opassword, $oserver) or die('Could not connect:');
?>

 

게시판이 보여질 화면을 구성한다.

view.php

view.php
0.01MB

view.php 실행 화면이다.

 

로그인에 필요한 회원가입을 하는 화면 구성이다.

id.html

id.html
0.00MB

id.html 실행 화면이다.

id.php

id.php
0.00MB

 

게시물 작성을 위한 insert.html, insert.php 구성이다.

insert.html

insert.html
0.00MB

insert.php

insert.php
0.00MB

insert 실행 화면이다.

 

로그인하지 않은 상태에서 다른 파일에 접근하지 못하도록 파일에 접근했을 때 로그인을 확인한다.

로그인이 되어있지 않은 상태에서는 로그인이 필요하다는 문구가 나온다.

login.php

login.php
0.00MB

login.php 실행화면

 

게시물을 보여줄 화면을 생성한다.

content.php

content.php
0.00MB

content의 실행화면이다.

 

게시물 삭제를 위한 구현이다.

del.php

del.php
0.00MB

del.php 실행화면이다.

 

4. 웹서버에 디렉토리 업로드

업로드할 디렉토리는 일단 zip으로 압축한다.

먼저 업로드할 디렉토리가 있는 위치로 접속한다.

윈도우 192.168.10.130 컴퓨터에서 ftp 192.168.11.137 으로 접속한다.

업로드할 디렉토리를 put으로 올린다.

C:\Users\st04>cd C:\Users\st04\web


C:\Users\st04\web>ftp 192.168.11.137
192.168.11.137에 연결되었습니다.
220 (vsFTPd 3.0.3)
200 Always in UTF8 mode.
사용자(192.168.11.137:(none)): web
331 Please specify the password.
암호: kitri03
230 Login successful.
ftp> put board.zip
200 PORT command successful. Consider using PASV.
150 Ok to send data.
226 Transfer complete.
ftp: 0.00초 51995.00KB/초
ftp>

 

웹서버 192.168.11.137의 /home/web 디렉토리에 파일이 잘 업로드된 것을 확인할 수 있다.

업로드된 파일을 Document Root(/home/httpd) 로 옮기고 unzip으로 압축을 푼다.

[root@CentOS8-3 ~]# cd /home/web
[root@CentOS8-3 web]# ls
board.zip httpd
[root@CentOS8-3 web]# mv /home/web/board.zip /home/httpd/html
[root@CentOS8-3 web]# cd /home/httpd/html
[root@CentOS8-3 html]# ls
20211001 20211022 20211105 20211119 20211203 board school
20211008 20211029 20211112 20211126 20211210 board.zip
[root@CentOS8-3 html]# rm -rf board
[root@CentOS8-3 html]# ls
20211001 20211022 20211105 20211119 20211203 board.zip
20211008 20211029 20211112 20211126 20211210 school
[root@CentOS8-3 html]# unzip board.zip
Archive: board.zip
creating: board/
inflating: board/conn.php
inflating: board/content.php
inflating: board/createboard.sql
inflating: board/del.php
inflating: board/id.html
inflating: board/id.php
inflating: board/insert.html
inflating: board/insert.php
inflating: board/login.php
inflating: board/view.php
inflating: board/논리모델.PNG
inflating: board/물리모델.PNG
[root@CentOS8-3 html]# ls
20211001 20211022 20211105 20211119 20211203 board school
20211008 20211029 20211112 20211126 20211210 board.zip

 

board가 잘 생성된 것을 확인할 수 있다.

 

5. 보안 구현

1) PW 저장된 해시값 다르게 설정한 사용자 인증 구현

사용자의 패스워드가 같아도 저장된 해시값은 달라 패스워드 추측이 어렵게 사용자 인증을 구현한다.

DBMS_CRYPTO.Hash(to_clob(to_char('$pw')),2)

 

다음과 같이 id값에 따른 pw 해시값을 저장한다.

DBMS_CRYPTO.Hash(to_clob(to_char(:v_id||:v_pw)),2)

 

id가 12인 것과 id가 1212인 것의 pw는 12로 동일하다. 하지만 password에 저장된 값은 password가 같이도 id값에 따라 pw 해시값을 저장하도록 하였다.

SQL> SELECT id, pw, name FROM id;


ID PW NAME
-------------------- -------------------------------------------------- ----------
12 A01610228FE998F515A72DD730294D87 12별명
34 14C879F3F5D8ED93A09F6090D77C2CC3 34별명
1212 93279E3308BDBBEED946FC965017F67A 1212별명

 

2) 로그인하지 않으면 파일 접근 불가능 구현

login.php를 통해 로그인이 있어야만 접근 가능한 파일에 로그인을 확인하도록 처리한다.

다음과 같이 로그인을 확인하도록 한다.

require('login.php');

 

로그인하지 않으면 다른 파일에 접근이 불가능하다는 것을 확인할 수 있다.

로그인하지 않고 다른 파일에 접근하면 로그인이 필요하다고 뜬다.

 

로그인을 하지 않으면 게시물에 접근이 불가능하다.

 

로그인하면 게시물에 접근 가능하다.

 

3) SQL Injection 예방 구현

아래와 같은 형태의 변수는 SQL Injection 공격이 가능하다.

$sql="select id, pw from id where id = '$id' and pw = DBMS_CRYPTO.Hash(to_clob(to_char('$pw')),2)";

 

SQL Injection 공격을 막기 위해 아래와 같이 bind 변수를 사용한다.

$sql="select id, pw from id where id = :v_id
and pw = DBMS_CRYPTO.Hash(to_clob(to_char(:v_id||:v_pw)),2)";

 

4) 게시글 작성자만 게시글 삭제 가능 구현

다음과 같은 sql문을 통해 게시물 작성자만 게시물이 삭제 가능하다.

$sql="delete from board where bno=:v_bno and id=:v_id";

 

하지만 게시물 작성자가 아닌 다른 아이디로 로그인하면 삭제 불가능한 것을 확인할 수 있다.

 

+ Recent posts