PHP empty session files generated by login system

前端 未结 4 1786
忘了有多久
忘了有多久 2021-01-11 22:48

Recently I\'ve noticed that many blank sessions are being created, I\'m not sure why though as I believe I\'m doing everything the correct way.

At the moment we crea

4条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-11 23:05

    Does session_regenerate_id(true) create a new session file and leave the old session file empty? That is the only reason I can think of for the empty session files?

    Calling session_regenerate_id(true) attempts to delete the session file but will return false if it fails to do (see relevant php source code below). For this reason I suggest you verify that your session functions run successfully i.e.

    if(!session_start()) {
      //log error 
    }
    
    if(!session_regenerate_id(true)) {
      //log error
    }
    

    Also check your settings for how frequently your garbage collector runs. Perhaps it runs on a very low probability and you're seeing orphaned sessions accumulate. The settings below will run the garbage collector with 1/100 (1%) probability each time php runs. Try deleting all orphans by setting both values to 1 for a single run and then setting the values to 1/100 like below.

    session.gc_probability = 1
    session.gc_divisor = 100
    

    Finally, your logout method expires the session cookie on browser close. Try expiring it immediately instead

    setcookie('auth', null, -1);
    

    PHP Source for session_regenerate_id

    https://github.com/php/php-src/blob/master/ext/session/session.c

    Note the call to PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC)

    /* {{{ proto bool session_regenerate_id([bool delete_old_session])
       Update the current session id with a newly generated one. If delete_old_session is set to true, remove the old session. */
    static PHP_FUNCTION(session_regenerate_id)
    {
        zend_bool del_ses = 0;
    
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &del_ses) == FAILURE) {
            return;
        }
    
        if (SG(headers_sent) && PS(use_cookies)) {
            php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot regenerate session id - headers already sent");
            RETURN_FALSE;
        }
    
        if (PS(session_status) == php_session_active) {
            if (PS(id)) {
                if (del_ses && PS(mod)->s_destroy(&PS(mod_data), PS(id) TSRMLS_CC) == FAILURE) {
                    php_error_docref(NULL TSRMLS_CC, E_WARNING, "Session object destruction failed");
                    RETURN_FALSE;
                }
                efree(PS(id));
                PS(id) = NULL;
            }
    
            PS(id) = PS(mod)->s_create_sid(&PS(mod_data), NULL TSRMLS_CC);
            if (PS(id)) {
                PS(send_cookie) = 1;
                php_session_reset_id(TSRMLS_C);
                RETURN_TRUE;
            } else {
                PS(id) = STR_EMPTY_ALLOC();
            }
        }
        RETURN_FALSE;
    }
    

    PS_DESTROY_FUNC

    https://github.com/php/php-src/blob/master/ext/session/mod_files.c

    Note VCWD_UNLINK which is a command to remove the file from disk.

    PS_DESTROY_FUNC(files)
    {
        char buf[MAXPATHLEN];
        PS_FILES_DATA;
    
        if (!ps_files_path_create(buf, sizeof(buf), data, key)) {
            return FAILURE;
        }
    
        if (data->fd != -1) {
            ps_files_close(data);
    
            if (VCWD_UNLINK(buf) == -1) {
                /* This is a little safety check for instances when we are dealing with a regenerated session
                 * that was not yet written to disk. */
                if (!VCWD_ACCESS(buf, F_OK)) {
                    return FAILURE;
                }
            }
        }
    
        return SUCCESS;
    }
    

提交回复
热议问题