본문 바로가기

개발과제

[노말틱 모의 해킹 취업반 4주차 개발과제 (1.5/2)] 회원가입 만들기, env파일

먼저 간단하게 보안 코딩을 하겠습니다

비밀번호 저장할 때 해시함수를 이용해서 암호화해서 저장하게 하겠습니다

 

그리고 회원가입할 때 주소 검색까지 추가하겠습니다.

여기서 주소는 집 위치를 뜻합니다! 이 코딩은 다음 포스팅에 다루겠습니다.

.

.

.

.

일단 비밀번호를 암호화해서 저장하게 코딩을 하겠습니다.

 

이때 사용되는 함수는 password_hash 입니다!

그리고 password_verify 함수 이용해 비밀번호를 비교할 수 있게 하겠습니다.

 

문법은 password_hash($password, PASSWORD_DEFAULT) 입니다.

PASSWORD_DEFAULT는 암호화 알고리즘을 나타내는 상수입니다.

이 값은 현재 시스템에서 가장 안전한 알고리즘을 자동으로 선택하게 합니다!

 

한 번 해봅시다

 

우선 회원가입을 할 때 암호화해서 저장되게 하겠습니다!

 

 

오늘은 할게 많네요

 

이 $login_pw을 바로 암호화하겠습니다.

 

$hashed_pw = password_hash($login_pw, PASSWORD_DEFAULT);

 

이 한 줄로 보안이 엄청 좋아진겁니다

 

그리고 원래 쿼리문 즉 sql문들에 $login_pw를 전부 $hashed_pw로 바꿔주겠습니다

 

 

이 한 줄밖에 없네요!

 

그리고 이제 process_login.php로 넘어가겠습니다.

 

 

여기서는 데이터베이스에 있는 비밀번호를 가져와서 비교하면 되니

password_verify 이용해서 확인하겠습니다!

 

일단 id 먼저 있는지 확인하고 그다음에 pw을 비교하게 하겠습니다.

 

 

수정본입니다

 

 

이러면 암호화 설정이 끝입니다

.

.

.

.

그리고 DB_INFO.php에 적은 비밀번호도 숨기겠습니다.

 

파일 권한으로 600 줘서 아예 다른 사용자가 못 보게 할 수 있지만 저희 서버도 못 보는 게 단점입니다.

 

그러니 대표적인 방법인 Apache2서버에 .env 파일에다가 저장하겠습니다!

 

 

우선 /etc/apache2 디렉터리로 이동합시다

 

#cd /etc/apache2

 

그리고 저희 데이터베이스 정보 저장할 정보를  envvars에 넣겠습니다

 

#sudo vi envvars

 

이렇게 작성합니다

 

 

패스워드 란에 자신의 비밀번호 적으셔야 됩니다!

 

그리고 저장 후 나가기 (:wq)

 

다음에 서버에 이 파일을 적용하겠습니다

 

#sudo systemctl restart apache2

 

그리고 DB_INFO.php 파일을 수정합니다

 

 

이제 저희의 중요한 정보가 노출 안 되네요!

 

좋습니다! 그리고 마지막으로 저희가 만든 .env 파일을 서버만 접근 가능하게 권한 추가 하겠습니다

 

우선 아파치서버의 httpd.conf 파일을 열겠습니다

 

#sudo vi /etc/apache2/httpd.conf

 

그리고 코드 추가하겠습니다

 

<Files ~ "^\.env>

      Order allow,deny

      Deny from all

      Satisfy all

</Files>

 

보안 위해서라면 뭐라도 해야죠

 

서버만 접근 가능하고 다른 사람은 접근을 못하게 설정하는 것입니다!

 

그리고 아파치서버 재실행하고 회원가입부터 해보겠습니다

 

#sudo systemctl restart apache2

 

일단 제 login_INFO에 있는 정보 전부 삭제하겠습니다

 

 

깨끗!

 

 

그리고 회원가입 하러 가보겠습니다

 

한 번에 됬음 좋겠네요

 

회원가입!

 

음.. 500오류면 서버 문제죠!

 

오류 찾아봅시다

#cat /var/log/apache2/error.log

 

이 파일에는 오류가 나올 때 오류 코드랑 설명을 합니다.

 

자세히 봐봅시다

 

저기 중간에 Data too long for column 'pw' 라 적혀있네요! 이 말은

제가 저장한 테이블 pw의 크기보다 암호화된 비밀번호가 더욱 크기 때문이라 안 들어가져서 오류 난 거네요

 

그럼 phpmyadmin 통해 pw의 크기를 충분히 늘리겠습니다

 

변경!

 

매우매우 크게 255로 했습니다

 

그리고 저장 후 다시 실행!

 

 

됬네요

 

그리고 로그인하기 전에 암호화가 잘 됐는지 확인해보겠습니다

 

쨘 비밀번호가 암호화가 잘된게 보입니다

 

이제 로그인해보겠습니다

 

*참고*

login.php에 비밀번호 입력란에 type을 password로 바꾸어서 안 보이게 했습니다

 

간단한 보안 설정입니다

 

로그인!

 

끝!

 

-login.php

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>HAPPY HACKING!</title>
    </head>
    <body>
        <h1>Login</h1>
        <form action="process_login.php" method="POST"> 
            <p><input type="text" name="id" placeholder="ID입력"></p>
            <p><input type="password" name="pw" placeholder="PW입력"></p>
            <p><input type="submit" value="로그인하기"></p>
        </form>
        <form action="join.php"> 
            <p><input type="submit" value="회원가입"></p>
        </form>
        <p>
        <?php session_start();
                if (isset($_SESSION['login_error'])) {
                    echo $_SESSION['login_error'];
                    unset($_SESSION['login_error']);
                }
        ?>
        </p>
    </body>
</html>

 

-process_join.php

<?php
    include 'DB_INFO.php'; //데이터 베이스 정보

    session_start(); //세션 시작

    //데이터베이스 연결
    $conn = mysqli_connect($host,$username,$password,$dbname);

    //데이터베이스 오류시 종료
    if(mysqli_connect_errno()) {
        die("데이터 베이스 오류: ". mysqli_connect_error());
    }

    //POST로 전달된 정보 받기
    $login_id = mysqli_real_escape_string($conn,$_POST['id']);
    $login_pw = mysqli_real_escape_string($conn,$_POST['pw']);

    //비밀번호는 암호화하기
    $hashed_pw = password_hash($login_pw, PASSWORD_DEFAULT);

    //ID 중복 검사용 sql문
    $check_id = "SELECT id FROM LOGIN_INFO WHERE id='$login_id' ";

    //중복 검사 sql문 실행
    $result_id = mysqli_query($conn, $check_id);

    if(mysqli_num_rows($result_id) > 0 ) { 
        //중복이 있을때
        $_SESSION['join_error'] = '아이디가 중복입니다!';
        header("Location: join.php");
    } else {
        //중복이 아닐때
        //새로운 사용자를 데이터베이스에 삽입문
        $sql = "INSERT INTO LOGIN_INFO (id, pw)
        VALUES ('$login_id','$hashed_pw')";

        //sql문 실행
        if(mysqli_query($conn,$sql)) {
            $_SESSION['join_error'] = '회원가입이 완료되었습니다!';
            header("Location: join.php");
        } else {
            $_SESSION['join_error'] = '회원가입 오류가 발생하였습니다.';
            header("Location: join.php");
        }

    }

    //회원가입 후 닫기
    exit();
?>

 

-process_login.php

 

<?php
    include 'DB_INFO.php'; //데이터 베이스 정보

    //데이터베이스 연결
    $conn = mysqli_connect($host,$username,$password,$dbname);

    session_start(); //세션 시작
    //오류시 종료
    if(mysqli_connect_errno()) {
        die("데이터 베이스 오류: ". mysqli_connect_error());
    }
    //POST로 전달된 정보 받기
    $login_id = mysqli_real_escape_string($conn,$_POST['id']);
    $login_pw = mysqli_real_escape_string($conn,$_POST['pw']);

    //ID 찾는 쿼리문
    $sql = "SELECT * FROM LOGIN_INFO WHERE id='$login_id'";

    //쿼리 실행
    $result = mysqli_query($conn, $sql);

    //쿼리 실행 결과 확인
    if(mysqli_num_rows($result) > 0 ) { 
        //ID있으니 비밀번호 검증
        $row = mysqli_fetch_array($result);
        $hashed_pw = $row['pw']; //결과 배열 중 pw을 가져온다
        if(password_verify($login_pw,$hashed_pw)) {
            //로그인 성공
            session_regenerate_id(); //ID 자동 갱신
            $_SESSION['login_id'] = $row['id'];
            header("Location: only_login.php");
        } else {
            //로그인 실패
            $_SESSION['login_error'] = "비밀번호가 일치하지 않습니다.";
            header("Location: login.php");
        }
    }
    else {
        //로그인 실패
        $_SESSION['login_error'] = '아이디 또는 비밀번호가 일치 하지 않습니다.';
        header("Location: login.php");
    }
?>

.

.

.

.

 

 

다음에 이제 회원가입할 때 주소까지 저장하고 주소 검색기능까지 넣겠습니다