-1

安全な方法でセッションを開始するためにこのコードを書きました

function sessionStart() {
    $session_name = 'sec_session_id'; // Set a custom session name
    $secure = false; // Set to true if using https.
    $httponly = true; // This stops javascript being able to access the session id. 

    ini_set('session.use_only_cookies', 1); // Forces sessions to only use cookies. 
    $cookieParams = session_get_cookie_params(); // Gets current cookies params.
    session_set_cookie_params($cookieParams["lifetime"], $cookieParams["path"], $cookieParams["domain"], $secure, $httponly); 
    session_name($session_name); // Sets the session name to the one set above.
    session_start(); // Start the php session
    session_regenerate_id(true); // regenerated the session, delete the old one. 
}

この session_regenrate_id があるかどうかについて質問があります。各ページでこれが実行されると、セッション ID が変更されますか? たとえば、$cookieParams["lifetime"] を 1 か月に増やすことは安全ですか?そうでない場合、1 か月間これを達成するにはどうすればよいですか? SSL を使用している場合、Cookie は安全だと思います。

アップデート

私が行く別の方法は、セッションをデータベースに保存することです。

      <?php
    /**
     * PDO Session Handler
     * @author Daniel15 <dan.cx>
     *
     * This class is actually static, but since PHP doesn't support static classes, abstract is close
     * enough. You do not instantiate the class; you just call the static "init" method.
     */
    abstract class PDOSession
    {
            private static $db;
            private static $oldData;
            /**
             * Initialise the PDO session handler
             * @param PDO PDO instance to use for database
             */
            public static function init(PDO $db)
            {
                    self::$db = $db;
                    // Add the session handlers
                    session_set_save_handler('PDOSession::open', 'PDOSession::close', 
                                             'PDOSession::read', 'PDOSession::write', 
                                             'PDOSession::destroy', 'PDOSession::garbageCollect');
                    session_start();
            }

            /**
             * Session open handler
             * @param string Path to save session to
             * @param string Name of the session
             */
            public static function open($save_path, $session_name)
            {
                    // Nothing
                    return true;
            }

            /**
             * Session close handler
             */
            public static function close()
            {
                    // Nothing
                    return true;
            }

            /**
             * Session load handler. Load the session
             * @param string Session ID
             */
            public static function read($session_id)
            {
                    // Load the session data from the database
                    $query = self::$db->prepare('
                            SELECT data
                            FROM sessions
                            WHERE session_id = :session_id');
                    $query->execute(array(':session_id' => $session_id));

                    return $query->fetchColumn();
            }

            /**
             * Session save handler. Save the session
             * @param string Session ID
             * @param string Data to save to session
             */
            public static function write($session_id, $data)
            {
                    /* Try to update the existing session. If we can't find one, then create a new one. If you
                     * are using MySQL, this can be done in a single INSERT statment via INSERT ... ON 
                     * DUPLICATE KEY UPDATE. Remove the UPDATE and edit the INSERT to do it this way.
                     * See http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
                     *
                     * This does two queries so you can use any DBMS.
                     */

                    $query = self::$db->prepare('
                            UPDATE sessions
                            SET data = :data, last_activity = :last_activity
                            WHERE session_id = :session_id');
                    $query->execute(array(
                            ':session_id' => $session_id,
                            ':data' => $data,
                            'last_activity' => time()));

                    // No session to update? Create a new one
                    if ($query->rowCount() == 0)
                    {
                            self::$db
                                    ->prepare('
                                            INSERT INTO sessions
                                                    (session_id, data, last_activity)
                                            VALUES
                                                    (:session_id, :data, :last_activity)')
                                    ->execute(array(
                                            ':session_id' => $session_id,
                                            ':data' => $data,
                                            'last_activity' => time())
                                    );
                    }
            }

            /**
             * Session delete handler. Delete the session from the database
             * @param string Session ID
             */
            public static function destroy($session_id)
            {
                    self::$db
                            ->prepare('
                                    DELETE FROM sessions
                                    WHERE session_id = :session_id')
                            ->execute(array(':session_id' => $session_id));
            }

            /**
             * Session garbage collector. Delete any old expired sessions
             * @param int How many seconds do sessions last for?
             */
            public static function garbageCollect($lifetime)
            {               
                    self::$db
                            ->prepare('
                                    DELETE FROM sessions
                                    WHERE last_activity < :min_time')
                            ->execute(array(':min_time' => time() - $lifetime));
            }
    }
?>

この場合、この状況でどのように Cookie を作成すればよいですか?

4

2 に答える 2

2

クッキーを使用する必要があります...

ここで、このチェックボックスに何かをさせる必要があります。つまり、チェックすると、ユーザーのユーザー名を記憶し、対応するログイン ページへの訪問ごとにユーザー名フィールドに入力します。そのために、Cookie を使用することにしました。上記で設定した「ID_my_site」ユーザー名 Cookie を使用できませんでした。これは、ユーザーがログアウトするたびに強制終了されていたためです。解決策は、次のように、ユーザー名も保存する「remember」という名前の追加の Cookie を作成することでした。

$year = time() + 31536000;
setcookie('remember_me', $_POST['username'], $year);

上記では、1 年間有効なこの追加の Cookie を追加しました。これにより、ユーザーがログインすると、ユーザーのユーザー名を保持する追加の Cookie が作成されます。ただし、現時点では使用されていません。変化:

<input type="text" name="username" maxlength="40">

に:

<input type="text" name="username" maxlength="40" value="<?php
echo $_COOKIE['remember_me']; ?>">

ログイン フォームでは、今後のアクセスのために、このユーザー名をテキスト フィールドに保存します。

まだ終わっていません。現在、コードはすべてのユーザーのこの情報を保存しています。この機能を具体的に要求したユーザーのみを記憶するようにしたいと考えています。これを行うには、追加の Cookie を作成する前に簡単なチェックを実行します。このチェックは、remember me チェックボックスがチェックされているかどうかを確認し、チェックされている場合にのみ新しい Cookie を作成します。そのようです:

if($_POST['remember']) {
setcookie('remember_me', $_POST['username'], $year);
}
elseif(!$_POST['remember']) {
    if(isset($_COOKIE['remember_me'])) {
        $past = time() - 100;
        setcookie(remember_me, gone, $past);
    }
}

上記のコードは、Cookie が存在するシナリオも処理しますが、ユーザーは、既存の Cookie を過去の時間に設定し、本質的にそれらを強制終了することによって、もはや記憶する必要がないことを識別しました。

ここでもっと読む...

于 2013-01-24T18:17:16.740 に答える
2

これがどのように機能するかを詳しく説明するには、すべてを書くよりも時間がかかります。しかし、これがどのように機能するかの概要を説明できるはずです。

PHP セッションは時間制限があります。それらは一定期間後にクリーンアップされます。PHP 構成でその時間を延長できますが、効果的であるほど長くはありません。

そのため、代替ログイン ルートを作成する必要があります。これを不注意に行うとセキュリティの抜け穴が開く可能性があるため、これは慎重に実装する必要があります。

この概念は、ユーザーに関連付けられ、ユーザー名とパスワードの代わりとして使用できる、1 回だけ使用できる一意の Cookie を作成することとして要約できます。

この Cookie は一意で、ランダムなデータで生成され、ユーザーに関連付けて保存される必要があります。時間制限があり (1 週間か 2 週間使用しないと期限切れになります)、使用すると再生成されます。

電子メール/パスワードなどのユーザー データを変更するには、ユーザーのパスワードが必要です。

Cookie の傍受をより困難にするために、サイトは SSL を使用する必要があります。

于 2013-01-24T18:30:53.290 に答える