Nice programing

30 분 후에 PHP 세션을 만료하려면 어떻게합니까?

nicepro 2020. 9. 27. 13:59
반응형

30 분 후에 PHP 세션을 만료하려면 어떻게합니까?


세션을 30 분 동안 유지 한 다음 제거해야합니다.


세션 시간 제한을 직접 구현해야합니다. 다른 사람이 언급 한 두 옵션 ( session.gc_maxlifetimesession.cookie_lifetime )은 신뢰할 수 없습니다. 그 이유를 설명하겠습니다.

먼저:

session.gc_maxlifetime
session.gc_maxlifetime 은 데이터가 '가비지'로 표시되고 정리되는 시간 (초)을 지정합니다. 세션 시작 중에 가비지 콜렉션이 발생합니다.

그러나 가비지 컬렉터 만의 확률로 시작 session.gc_probability 로 나눈 session.gc_divisor는 . 이러한 옵션에 대한 기본값 (각각 1과 100)을 사용하면 확률은 1 %에 불과합니다.

글쎄, 가비지 수집기가 더 자주 시작되도록 이러한 값을 간단히 조정할 수 있습니다. 그러나 가비지 수집기가 시작되면 등록 된 모든 세션의 유효성을 확인합니다. 그리고 그것은 비용 집약적입니다.

또한 PHP의 기본 session.save_handler 파일을 사용하는 경우 세션 데이터는 session.save_path에 지정된 경로의 파일에 저장됩니다 . 해당 세션 핸들러를 사용하면 세션 데이터의 수명은 마지막 액세스 날짜가 아닌 파일의 마지막 수정 날짜에 계산됩니다.

참고 : 기본 파일 기반 세션 핸들러를 사용하는 경우 파일 시스템은 액세스 시간 (atime)을 추적해야합니다. Windows FAT는 그렇지 않으므로 FAT 파일 시스템 또는 시간 추적을 사용할 수없는 다른 파일 시스템에 갇혀있는 경우 세션 가비지 수집을 처리 할 다른 방법을 찾아야합니다. PHP 4.2.3부터 atime 대신 mtime (수정 날짜)을 사용했습니다. 따라서 시간 추적을 사용할 수없는 파일 시스템에는 문제가 없습니다.

따라서 세션 데이터가 최근에 업데이트되지 않았기 때문에 세션 자체가 여전히 유효한 것으로 간주되는 동안 세션 데이터 파일이 삭제 될 수도 있습니다.

두 번째 :

session.cookie_lifetime
session.cookie_lifetime 은 브라우저로 전송되는 쿠키의 수명을 초 단위로 지정합니다. […]

네, 맞습니다. 이것은 쿠키 수명에만 영향을 미치며 세션 자체는 여전히 유효 할 수 있습니다. 그러나 세션을 무효화하는 것은 클라이언트가 아닌 서버의 작업입니다. 그래서 이것은 아무것도 도움이되지 않습니다. 실제로 session.cookie_lifetime을로 설정 0하면 세션의 쿠키가 브라우저가 닫힐 때까지만 유효한 실제 세션 쿠키 가됩니다.

결론 / 최상의 솔루션 :

가장 좋은 해결책은 자신의 세션 시간 제한을 구현하는 것입니다. 마지막 활동 (예 : 요청)의 시간을 나타내는 간단한 타임 스탬프를 사용하고 모든 요청으로 업데이트합니다.

if (isset($_SESSION['LAST_ACTIVITY']) && (time() - $_SESSION['LAST_ACTIVITY'] > 1800)) {
    // last request was more than 30 minutes ago
    session_unset();     // unset $_SESSION variable for the run-time 
    session_destroy();   // destroy session data in storage
}
$_SESSION['LAST_ACTIVITY'] = time(); // update last activity time stamp

모든 요청에서 세션 데이터를 업데이트하면 세션 파일의 수정 날짜도 변경되어 가비지 수집기에 의해 세션이 너무 일찍 제거되지 않습니다.

또한 추가 타임 스탬프를 사용하여 세션 ID를 주기적으로 재생성하여 세션 고정 과 같은 세션 에 대한 공격을 방지 할 수 있습니다 .

if (!isset($_SESSION['CREATED'])) {
    $_SESSION['CREATED'] = time();
} else if (time() - $_SESSION['CREATED'] > 1800) {
    // session started more than 30 minutes ago
    session_regenerate_id(true);    // change session ID for the current session and invalidate old session ID
    $_SESSION['CREATED'] = time();  // update creation time
}

메모:

  • session.gc_maxlifetime 이 사용자 지정 만료 처리기의 수명 (이 예에서는 1800) 이상이어야합니다.
  • 시작 후 30 분 이후가 아니라 활동 30 분 후 세션을 만료하려는 경우 , 세션 쿠키를 활성 상태로 유지하기 위해 만료와 함께을 사용해야 합니다.setcookietime()+60*30

PHP 세션이 30 분 안에 만료되는 간단한 방법입니다.

참고 : 시간을 변경하려면 원하는 시간으로 30을 변경하고 변경하지 마십시오. * 60 : 분이 표시됩니다.


분 : (30 * 60)
일 : (n * 24 * 60 * 60) n = 일수


Login.php

<?php
    session_start();
?>

<html>
    <form name="form1" method="post">
        <table>
            <tr>
                <td>Username</td>
                <td><input type="text" name="text"></td>
            </tr>
            <tr>
                <td>Password</td>
                <td><input type="password" name="pwd"></td>
            </tr>
            <tr>
                <td><input type="submit" value="SignIn" name="submit"></td>
            </tr>
        </table>
    </form>
</html>

<?php
    if (isset($_POST['submit'])) {
        $v1 = "FirstUser";
        $v2 = "MyPassword";
        $v3 = $_POST['text'];
        $v4 = $_POST['pwd'];
        if ($v1 == $v3 && $v2 == $v4) {
            $_SESSION['luser'] = $v1;
            $_SESSION['start'] = time(); // Taking now logged in time.
            // Ending a session in 30 minutes from the starting time.
            $_SESSION['expire'] = $_SESSION['start'] + (30 * 60);
            header('Location: http://localhost/somefolder/homepage.php');
        } else {
            echo "Please enter the username or password again!";
        }
    }
?>

HomePage.php

<?php
    session_start();

    if (!isset($_SESSION['luser'])) {
        echo "Please Login again";
        echo "<a href='http://localhost/somefolder/login.php'>Click Here to Login</a>";
    }
    else {
        $now = time(); // Checking the time now when home page starts.

        if ($now > $_SESSION['expire']) {
            session_destroy();
            echo "Your session has expired! <a href='http://localhost/somefolder/login.php'>Login here</a>";
        }
        else { //Starting this else one [else1]
?>
            <!-- From here all HTML coding can be done -->
            <html>
                Welcome
                <?php
                    echo $_SESSION['luser'];
                    echo "<a href='http://localhost/somefolder/logout.php'>Log out</a>";
                ?>
            </html>
<?php
        }
    }
?>

LogOut.php

<?php
    session_start();
    session_destroy();
    header('Location: http://localhost/somefolder/login.php');
?>

설정된 시간 후에 사용자를 로그 아웃하는 것입니까? 등록시 세션 생성 시간 (또는 만료 시간)을 설정 한 다음 각 페이지로드에서이를 확인할 수 있는지 확인합니다.

예 :

$_SESSION['example'] = array('foo' => 'bar', 'registered' => time());

// later

if ((time() - $_SESSION['example']['registered']) > (60 * 30)) {
    unset($_SESSION['example']);
}

편집 : 나는 당신이 다른 것을 의미한다고 생각합니다.

session.gc_maxlifetimeini 설정 을 사용하여 특정 수명 후에 세션을 스크랩 할 수 있습니다 .

편집 : ini_set ( 'session.gc_maxlifetime', 60 * 30);


이 게시물은 세션 시간 제한을 제어하는 ​​몇 가지 방법을 보여줍니다. http://bytes.com/topic/php/insights/889606-setting-timeout-php-sessions

IMHO 두 번째 옵션은 좋은 솔루션입니다.

<?php
/***
 * Starts a session with a specific timeout and a specific GC probability.
 * @param int $timeout The number of seconds until it should time out.
 * @param int $probability The probablity, in int percentage, that the garbage 
 *        collection routine will be triggered right now.
 * @param strint $cookie_domain The domain path for the cookie.
 */
function session_start_timeout($timeout=5, $probability=100, $cookie_domain='/') {
    // Set the max lifetime
    ini_set("session.gc_maxlifetime", $timeout);

    // Set the session cookie to timout
    ini_set("session.cookie_lifetime", $timeout);

    // Change the save path. Sessions stored in teh same path
    // all share the same lifetime; the lowest lifetime will be
    // used for all. Therefore, for this to work, the session
    // must be stored in a directory where only sessions sharing
    // it's lifetime are. Best to just dynamically create on.
    $seperator = strstr(strtoupper(substr(PHP_OS, 0, 3)), "WIN") ? "\\" : "/";
    $path = ini_get("session.save_path") . $seperator . "session_" . $timeout . "sec";
    if(!file_exists($path)) {
        if(!mkdir($path, 600)) {
            trigger_error("Failed to create session save path directory '$path'. Check permissions.", E_USER_ERROR);
        }
    }
    ini_set("session.save_path", $path);

    // Set the chance to trigger the garbage collection.
    ini_set("session.gc_probability", $probability);
    ini_set("session.gc_divisor", 100); // Should always be 100

    // Start the session!
    session_start();

    // Renew the time left until this session times out.
    // If you skip this, the session will time out based
    // on the time when it was created, rather than when
    // it was last used.
    if(isset($_COOKIE[session_name()])) {
        setcookie(session_name(), $_COOKIE[session_name()], time() + $timeout, $cookie_domain);
    }
}

위의 답변이 정확하지만 응용 프로그램 수준에 있음을 이해합니다. .htaccess파일을 사용하여 만료 시간을 설정 하지 않는 이유는 무엇입니까?

<IfModule mod_php5.c>
    #Session timeout
    php_value session.cookie_lifetime 1800
    php_value session.gc_maxlifetime 1800
</IfModule>

if (isSet($_SESSION['started'])){
    if((mktime() - $_SESSION['started'] - 60*30) > 0){
        //Logout, destroy session, etc.
    }
}
else {
    $_SESSION['started'] = mktime();
}

사용 session_set_cookie_params이을위한 funciton를.

호출하기 전에이 함수를 session_start()호출 해야 합니다.

이 시도:

$lifetime = strtotime('+30 minutes', 0);

session_set_cookie_params($lifetime);

session_start();

자세한 내용은 http://php.net/manual/function.session-set-cookie-params.php를 참조하십시오.


다음과 같은 기능으로 실제로 쉽습니다. 'id'및 'time'필드와 함께 데이터베이스 테이블 이름 'sessions'를 사용합니다.

사용자가 사이트 나 서비스를 다시 방문 할 때마다이 함수를 호출하여 반환 값이 TRUE인지 확인해야합니다. FALSE 인 경우 사용자가 만료되고 세션이 삭제됩니다 (참고 :이 함수는 데이터베이스 클래스를 사용하여 데이터베이스를 연결하고 쿼리합니다. 물론 함수 내에서 수행 할 수도 있습니다.)

function session_timeout_ok() {
    global $db;
    $timeout = SESSION_TIMEOUT; //const, e.g. 6 * 60 for 6 minutes
    $ok = false;
    $session_id = session_id();
    $sql = "SELECT time FROM sessions WHERE session_id = '".$session_id."'";
    $rows = $db->query($sql);
    if ($rows === false) {
        //Timestamp could not be read
        $ok = FALSE;
    }
    else {
        //Timestamp was read succesfully
        if (count($rows) > 0) {
            $zeile = $rows[0];
            $time_past = $zeile['time'];
            if ( $timeout + $time_past < time() ) {
                //Time has expired
                session_destroy();
                $sql = "DELETE FROM sessions WHERE session_id = '" . $session_id . "'";
                $affected = $db -> query($sql);
                $ok = FALSE;
            }
            else {
                //Time is okay
                $ok = TRUE;
                $sql = "UPDATE sessions SET time='" . time() . "' WHERE session_id = '" . $session_id . "'";
                $erg = $db -> query($sql);
                if ($erg == false) {
                    //DB error
                }
            }
        }
        else {
            //Session is new, write it to database table sessions
            $sql = "INSERT INTO sessions(session_id,time) VALUES ('".$session_id."','".time()."')";
            $res = $db->query($sql);
            if ($res === FALSE) {
                //Database error
                $ok = false;
            }
            $ok = true;
        }
        return $ok;
    }
    return $ok;
}

세션에 타임 스탬프 저장


<?php    
$user = $_POST['user_name'];
$pass = $_POST['user_pass'];

require ('db_connection.php');

// Hey, always escape input if necessary!
$result = mysql_query(sprintf("SELECT * FROM accounts WHERE user_Name='%s' AND user_Pass='%s'", mysql_real_escape_string($user), mysql_real_escape_string($pass));

if( mysql_num_rows( $result ) > 0)
{
    $array = mysql_fetch_assoc($result);    

    session_start();
    $_SESSION['user_id'] = $user;
    $_SESSION['login_time'] = time();
    header("Location:loggedin.php");            
}
else
{
    header("Location:login.php");
}
?>

이제 타임 스탬프가 허용 된 시간 범위 (1800 초는 30 분) 내에 있는지 확인합니다.

<?php
session_start();
if( !isset( $_SESSION['user_id'] ) || time() - $_SESSION['login_time'] > 1800)
{
    header("Location:login.php");
}
else
{
    // uncomment the next line to refresh the session, so it will expire after thirteen minutes of inactivity, and not thirteen minutes after login
    //$_SESSION['login_time'] = time();
    echo ( "this session is ". $_SESSION['user_id'] );
    //show rest of the page and all other content
}
?>

Please use following block of code in your include file which loaded in every pages.

$expiry = 1800 ;//session expiry required after 30 mins
    if (isset($_SESSION['LAST']) && (time() - $_SESSION['LAST'] > $expiry)) {
        session_unset();
        session_destroy();
    }
    $_SESSION['LAST'] = time();

Using timestamp...

<?php
if (!isset($_SESSION)) {
    $session = session_start();
} 
if ($session && !isset($_SESSION['login_time'])) {
    if ($session == 1) {
        $_SESSION['login_time']=time();
        echo "Login :".$_SESSION['login_time'];
        echo "<br>";
        $_SESSION['idle_time']=$_SESSION['login_time']+20;
        echo "Session Idle :".$_SESSION['idle_time'];
        echo "<br>";
    } else{
        $_SESSION['login_time']="";
    }
} else {
    if (time()>$_SESSION['idle_time']){
        echo "Session Idle :".$_SESSION['idle_time'];
        echo "<br>";
        echo "Current :".time();
        echo "<br>";
        echo "Session Time Out";
        session_destroy();
        session_unset();
    } else {
        echo "Logged In<br>";
    }
}
?>

I have used 20 seconds to expire the session using timestamp.

If you need 30 min add 1800 (30 min in seconds)...


Use this class for 30 min

class Session{
    public static function init(){
        ini_set('session.gc_maxlifetime', 1800) ;
        session_start();
    }
    public static function set($key, $val){
        $_SESSION[$key] =$val;
    }
    public static function get($key){
        if(isset($_SESSION[$key])){
            return $_SESSION[$key];
        } else{
            return false;
        }
    }
    public static function checkSession(){
        self::init();
        if(self::get("adminlogin")==false){
            self::destroy();
            header("Location:login.php");
        }
    }
    public static function checkLogin(){
        self::init();
        if(self::get("adminlogin")==true){
            header("Location:index.php");
        }
    }
    public static function destroy(){
        session_destroy();
        header("Location:login.php");
    }
}

You can straight use a DB to do it as an alternative. I use a DB function to do it that I call chk_lgn.

Check login checks to see if they are logged in or not and, in doing so, it sets the date time stamp of the check as last active in the user's db row/column.

I also do the time check there. This works for me for the moment as I use this function for every page.

P.S. No one I had seen had suggested a pure DB solution.

참고URL : https://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes

반응형