본문 바로가기
Etc/경험담

[PHP] 웹사이트

by 생각하는달팽이 2015. 8. 6.

회원가입


회원가입 첫 페이지 로드시 

 

1. [보안] 도메인 체크

if ($_SERVER['HTTP_HOST'] != 'domain'){
  exit('허용되지 않은 도메인 입니다.');
}


2. 로그인 세션 체크 ( 만일, 로그인 상태일 경우 메인페이지로 강제 이동 )

if($_SESSION['session_id']){
    header('Location: '.$url);
    exit;
}


3. SSL 관련 처리

if(!isset($_SERVER["HTTPS"])){
    $url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
header('Location: '.$url);
}


4. i-Pin 인증 , 본인인증(휴대폰)

해당 부분의 경우 form 태그를 이용하여 관련 리퀘스트를 만들어 요청하고, 반환값을 갖고 처리한다.


5. 이용약관 동의

자바스크립트를 이용하여 해당 체크박스가 체크되어 있는지 확인 후 진행한다.




로그인


1. 로그인 데이터 넘기기

: 폼 태그를 이용하여 아이디, 패스워드 넘김



2. [보안] 도메인 체크

if ($_SERVER['HTTP_HOST'] != 'domain'){
  exit('허용되지 않은 도메인 입니다.');
}

3. 외부로부터 생성된 폼 데이터 전송 방지


function referer(){

	$http_referer = str_replace('http://','',$_SERVER['HTTP_REFERER']);
	$http_referer = str_replace('https://','',$http_referer);

	$referer = explode('/',$http_referer);
	
	if ($referer[0] <> $_SERVER['HTTP_HOST']) {

		//경고창 띄우기 스크립트로 처리하면 편함 echo '....';
		exit;
	}

}

4. 넘어온값 확인

$user_id = trim( $_POST['userid'] );

$user_id= $mysqli_accountdb_s1->real_escape_string( $userid );// sql injection 방지

$pw = trim( $_POST['password'] );

$backurl = trim( $_POST['backurl'] );
if (!$backurl) {
	$backurl = trim( $_GET['backurl'] ); // 로그인이 완료되면 되돌아갈 url
}
$backurl = xss_replace($backurl); // 크로스 사이트 스크립트 방지 함수를 통한 문자열 처리

if (!$backurl) {
	$backurl = '메인주소 설정'; // 만일 돌아갈 url 없으면 메인 주소로 설정
}

5. 해싱

$encode_pw = sha1($pw);


6. 세션을 이용한 연속 로그인 딜레이 처리 

if($_SESSION['ss_logintime'] != '') {
	$chk_time = mktime(date("H"),date("i"),date("s")-10,date("m"),date("d"),date("Y"));
	
	if ($chk_time < strtotime($_SESSION['ss_logintime'])) {
		$msg = "로그인이 진행 중 입니다. 잠시 기다려 주십시오.";
		msg($msg); // 알림 띄우기
		ob_flush();
		flush();
		sleep(2);
	}
}

$_SESSION['ss_logintime'] = date('Y-m-d H:i:s');


7.IP 체크

쿠키를 이용한 IP 체크 + 로그인 횟수 제한 ( 10회 이하 ) > 10분간 제한둠 ( 쿠키에 로그인 시간 담고 처리 )


8. 로그인 매크로 체크

무작위 대입법을 이용한 해킹 방지


9. 실제 유저 체크 

유저가 존재하는지 , 탈퇴유저가 아닌지 ,비밀번호가 맞는지 _ 해당부분은 query 로 체크해도 되고, php 내부에서 체크해도 됨.


10. 해외 IP 차단 유저 체크

해외 IP 차단을 통한 우회 해킹 방지.


11. 로그인 실패 횟수 누적 5회 이상 로그인 불가 > 비번찾기로 유도

로그인 실패 횟수가 5회 이상일 경우 , 비번찾기 페이지로 리다이렉트


12. 로그인 시작

세션 생성.


13. 유저 정보 최종 로그인 정보 업데이트

session_id , 로그인 실패 횟수, 로그인 날짜, 로그인 ip


14. 로그인 히스토리 추가

로그인 히스토리 테이블에 로그인 기록을 남깁니다.


15. 간편회원,페이스북회원 체크

정회원 전환 메뉴로 강제 이동.


16. 비밀번호 변경 체크

비밀번호 변경 후 90일이 지났는지 확인합니다.


MySQL


1. Insert 가 에러가 났을 경우에도 auto_increment 값은 증가해있다.

실제, MySQLi 를 이용하여 insert 쿼리문을 날린 후 duplicate 등의 에러로 레코드가 쌓이지 않아도. 해당 auto_increment key 값은 +1 증가되어 있다.

 다음 article 에서는 이를 MySQL 버그라고 얘기한다.

(http://desmart.com/blog/be-careful-with-mysqls-auto-increment-how-we-ended-up-losing-data)

 QA


1. &#65279

만일, 출력된 화면에 다음과 같은 코드가 표시되고 의도했던 echo 값이 안나올 경우. &#65279;

해당 부분은 'encoding 문제이다'

해결책으로는 notepad++ 를 이용하여 해당 파일의 인코딩을 UFT-8 (BOM 없음) 으로 해당 소스를 인코딩해주면 해결이 된다.


2. HTML 파일에서 PHP 코드를 실행시키려면


(1) httpd.conf 파일내 아래의 내용을 입력한다.

AddHandler application/x-httpd-php .html


(2) .htaccess 파일안에 아래의 내용을 입력한다.


AddType application/x-httpd-php .html


3. global 이 뭔가욤?

global 은 함수에서 사용하는 변수가 전역변수와 이름이 같을때, 전역변수를 가져다 쓸 수 있도록 해주는 녀석입니다.

ios 쪽 코드에서는 self.변수명 이런 느낌이라고 생각하면 편합니다.






참고사항


[SERVER]

$_SERVER['REQUEST_URI'] = 현재페이지의 주소에서 도메인 제외 =  index.phpuser=&name=

$_SERVER['PHP_SELF'] = 현재페이지의 주소에서 도메인과 넘겨지는 값 제외 = index.php


[required or required_once , include or include_once ]

본래 required , include  대신 required_once , include_once 를 사용하였다.

해당 api 를 쓰는 이유는 중복 함수를 피하기 위해서다.

그러나, 해당 api 는 속도를 떨어뜨린다고 한다.

그러므로 다음과 같이 사용하는게 더 좋다고 한다.


if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}


아래는 비교한 결과이다. 


                php                  hhvm
if defined      0.18587779998779     0.046600103378296
require_once    1.2219581604004      3.2908599376678


[추가 TIP]


echo가 print 보다 빠르다. 


string을 감싸는데 있어서 작은따옴표(') 가 큰따옴표(")보다 빠르다.

그 이유는 PHP는 큰따옴표안에서 변수를 찾고 작은 따옴표에서는 변수를 찾지 않기 때문이다.

string에 변수가 없다면 작은따옴표를 사용해라.


미리 계산한 값을 사용해라. for루프를 위해서 가장큰값을 지정할때 루프에 넣지말고 

$max = count($array)를 for 루프가 시작하기 전에 사용해라 


for($x=0;$x<count($array);$x++) ==> for($x=0;$x<$max;$x++) 


메모리 해제를 위해서 크기가 큰 배열은 unset or null 처리를 해야한다.


str_replace가 preg_replace보다 빠르다. str_replace는 왠만하면 최고고, 그러나 strstr이 때대로 큰 string에서 좀더 빠르다. str_prelace안에 배열을 사용하는 것이 보통 여러개의 str_replace를 쓰는 것보다 빠르다. 


else if 구문이 switch보다 빠르다 


사용하고 데이터베이스 connection을 닫아라 


$row['id']가 $row[id]보다 7배가 빠르다. 작은따옴표를 사용하지 않으면, 시스템이 무엇이 당신이 의미한 인덱스인지 추측해야한다. 


php를 선언할때는 <?php ... ?> 을 사용하자. 다른 스타일은 모두 불량 



엄격한 코드를 사용하자, notice와 warning, error를 안보이게 하는것을 피하자. 좀더 깨끗한 코드와 덜 부하가 되는 결과를 나타낸다. error_reporting(E_ALL) 을 항상 켜놓는 것을 고려하자. 



header('location:'.$url);을 사용할때는 exit를 함께 사용하는것을 기억해라

location이 바뀌었음에도 불구하고 스크립트는 계속 진행된다. 


변수는 미리 초기화하여 사용하자. 그렇지 않으면 매우 느리다.


에러를 보이지 않게 하는 @는 매우느리다


단순 SELECT 기능을 사용할때는 GET 메소드를, UPDATE 기능을 사용할때는 POST 를 이용하여 통신하는게 좋다

왜냐면, GET 의 경우 캐싱이되어 속도가 상대적으로 빠르다. ( POST  는 캐싱 되지 않는다. )



 PHP 5.2.9 에서는 array() 녀석이 '[ ]' 를 해석하지 못합니다. 주의

만일, 기존 소스가 '[ ]' 를 이용하여 배열을 쓰고 있다면 이를 5.2.9 버전에서는 array() 로 바꾸어주어야 합니다.



Do not use preg_match() 

if you only want to check if one string is contained in another string. 

Use  strpos() or strstr() instead as they will be faster.


반응형

'Etc > 경험담' 카테고리의 다른 글

[Unity] 4.6.9p2 빌드시 오류 경험.  (3) 2015.12.18
[git] git 설정  (0) 2015.08.07
[windows] 개발 환경 작업  (0) 2015.08.04
[Rankup] 랭크업 플랫폼 수정기  (0) 2015.08.04
[ruby on rails] 경험담  (0) 2015.03.16