질문을 삭제하지 말아주세요.!
 
2
1
0

안녕하세요.

현재 admin login panel을 이용해서 login session 파트를 공부하고 있습니다.

로그인 로그아웃 모두 다 작동이되고 마지막 로그인날짜까지 가져오는 건 구현했는데

로그인할때 3번 시도 후 실패하면 몇 분뒤에 다시 로그인해달라고 lockout을 걸고싶은데

하다가 막혔습니다.. 제 스크립트에 문제가 많이 있는건가요?

혼자 독학하면서 하느라 코딩이 매끄럽지 못합니다..

부탁드리겠습니다.


CREATE TABLE `tbl_user` (

  `user_id` smallint(5) UNSIGNED NOT NULL,

  `user_fname` varchar(50) NOT NULL,

  `user_lname` varchar(50) NOT NULL,

  `user_name` varchar(50) NOT NULL,

  `user_email` varchar(100) NOT NULL,

  `user_pass` varchar(50) NOT NULL,

  `user_level` varchar(25) NOT NULL,

  `user_ip` varchar(100) NOT NULL,

  `user_lastLogin` datetime NOT NULL,

  `user_failedLog` varchar(5) NOT NULL

) ENGINE=InnoDB DEFAULT CHARSET=utf8;



user.php

<?php
 
function editUser($id, $fname, $lname, $username, $email, $password)
{
    include("connect.php");
    $updatestring = "UPDATE tbl_user SET user_fname='{$fname}', user_lname='{$lname}', user_name='{$username}', user_email='{$email}', user_pass='{$password}' WHERE user_id={$id}";
    $updatequery  = mysqli_query($link, $updatestring);
     
    if ($updatequery) {
        redirect_to("admin_index.php");
    } else {
        $message = "Not going to happen!";
        return $message;
    }
    mysqli_close($link);
}
 
function getUser($id)
{
    require_once("connect.php");
    $userstring = "SELECT * FROM tbl_user WHERE user_id={$id}";
    $userquery  = mysqli_query($link, $userstring);
     
    if ($userquery) {
        //fetch
        $found_user = mysqli_fetch_array($userquery, MYSQLI_ASSOC);
        return $found_user;
    } else {
        $message = "There was a problem finding your account. Please return all of your access cards to the frint desk and get the F out!";
        return $message;
        //return
    }
    //create query ,run query , gather object, fetch array, return, else, error messege
    mysqli_close($link);
}
 
 
function createUser($fname, $lname, $username, $email, $password, $level)
{
    require_once("connect.php");
    $ip = 0;
     
    //Passwords Hashing
    $encryptPw = sha1($password);
     
    $userstring = "INSERT INTO tbl_user VALUES(NULL,'{$fname}','{$lname}','{$username}','{$email}','{$encryptPw}','{$level}','{$ip}','user_lastLogin','user_failedLog')"; //matter not having same row as at tbl
     
    //echo $userstring;
     
    $to   = "{$email}";
    $subj = "Verify your account from London Yoga";
    $body = "Your admin account has been crated.\n Please click the following link to log in.\nhttp://jesspark.ca/Park_S_3014_r2/admin_login.php\n Username:{$username}\n Password:{$password}";
    mail($to, $subj, $body);
     
    mail($to, $subj, $body);
     
    $userquery = mysqli_query($link, $userstring);
    if ($userquery) {
        redirect_to("admin_index.php");
         
         
    } else {
        $message = "Your hiring practices have failed you, we can not keep this individual.";
        return $message;
         
    }
     
    mysqli_close($link);
     
}
 
function hasingPw($length = 6)
{
    $charsSet = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $countStr = mb_strlen($charsSet);
     
    for ($i = 0, $result = ''; $i < $length; $i++) {
        $index = rand(0, $countStr - 1);
        $result .= mb_substr($charsSet, $index, 1);
    }
     
    return $result;
}
 
?>


admin.login.php

<?php
//turn on error report, pc is automatically on
ini_set('display_errors', 1);
error_reporting(E_ALL);
 
$ip = $_SERVER["REMOTE_ADDR"]; //get the ip address
//echo $ip;
 
require_once("phpscripts/init.php");
 
if (isset($_POST['submit'])) {
    $username = trim($_POST['username']);
     
    $password = sh1(trim($_POST['password']));
     
    if ($username != "" && $password != "") {
        $result  = logIn($username, $password, $ip);
        $message = $result;
        //echo "All good.";
         
    } else {
        $message = "Please fill in the required fields.";
         
    }
}
 
?>
 
<!doctype html>
<html>
   <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
      <title>Welcome to London Yoga</title>
      <link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
      <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
      <link href="css/reset.css" rel="stylesheet" type="text/css" media="screen">
      <link href="css/foundation.css" rel="stylesheet" type="text/css" media="screen">
      <link href="css/main.css" rel="stylesheet" type="text/css" media="screen">
   </head>
   <body>
      <div class="row text-center contents">
         <img class="logo" src="images/logo.png" alt="London yoga logo">
         <h1>London Yoga Admin Panel</h1>
         <?php if(!empty($message)) {echo $message;} ?>
         <h2 class="hide">Admin Panel Login Form</h2>
         <div class="small-12 medium-6 large-6 columns login">
            <form id="loginForm" action="admin_login.php" method="post">
               <label>Username:</label>
               <input type="text" name="username" value="">
               <label>Password:</label>
               <input type="password" name="password" value="">
               <input class="loginBtn" type="submit" name="submit" value="Sign In">
            </form>
         </div>
      </div>
   </body>
</html>
    CommentAdd your comment...

    4 answers

    1.  
      1
      0
      -1

      테이블을 하나 더 만들어서 아이디별 로그인 실패 횟수와 시도시간을 테이블에 넣고

      테이블에서 횟수를 늘리거나 시도시간을 확인해서 5분이 지나면 테이블에서 지우는 식으로 구현하면 될것 같습니다.

      아니면 Redis같은데다 5분짜리 타임아웃으로 카운트를 집어넣으셔도 되구요.

      1. jesspark

         답변 감사드려요. 말씀하신 로그인 실패횟수는 제가 만들어놓은 user_failedLog 테이블과 상응하는거같고 시도횟수테이블을 만들어야겠네요. 감사합니다.  Redis는 처음봤는데 찾아봐야겠어요. 감사합니다!!

      2. 아스트린

        user_failedLog 테이블에 count 칼럼을 하나 추가해서 사용하셔도 괜찮을거 같네요

      3. jesspark

        감사합니다!!

        처음에 말씀하신 방법말고 그냥 failedLog 테이블에  count column 추가하라는 말씀이시죠?

      4. 아스트린

        제가 failedLog 테이블이 없다고 생각하고 이야기한거라 처음에 말한 방법도 같은 뜻입니다.

        테이블을 분리할거냐 말거냐는 선택의 영역이니 편하신 대로 하세요. 개인적으로는 한 테이블에 넣어두는 쪽이 지울 때 하나만 지우면 되서 좋아합니다 ㅎㅎ

      CommentAdd your comment...
    2.  
      4
      3
      2

      로그인 쓰로틀링은 라라벨에 이미 포함되어 있습니다. 필요한 잘못된 로그인 허용 횟수와, 초과시 계정을 잠글 시간등의 값만 설정해 주면 됩니다. https://laravel.kr/docs/5.4/authentication#login-throttling

        CommentAdd your comment...
      1.  
        1
        0
        -1

        저희는 보안정보는 DB 를 따로 분리해서 저장했습니다.

        이런 정보를 담고 있죠

        • 마지막 패스워드 실패시간
        • 연속 패스워드 실패 횟수
        • 총 패스워드 실패 횟수
        • 기타 등등


        패스워드 실패할때마다 패스워드 실패횟수 증가시키고

        로그인 성공하면 연속 패스워드 실패 횟수는 리셋 시켰습니다.

        (총 패스워드 실패 횟수는 유저가 확인하고 리셋하도록 처리)


        jesspark 님의 로직이라면...

        1. 연속 패스워드 실패 횟수가 3 보다 클 경우
        2. 마지막 패스워드 실패시간과 현재시간이 5분 이하일 경우

        로그인을 차단 시키면 되겠네요.


          CommentAdd your comment...
        1.  
          1
          0
          -1

          우선 로그인시도 할때 마지막 시도시간이 5분이 넘었다면 로그인시도 카운터를 초기화하는 부분이 필요할꺼같네요

          1. jesspark

            답변 감사드립니다.  $attempts = 0 값을 설정하라는 말씀이신가요? 정말 초보라서 Karll 님께서 답변하신걸 어떻게 구현해야 되는지 모르겠습니다..


          CommentAdd your comment...