处理会话cookie生存期和登录过程。PHP

处理会话cookie生存期和登录过程。PHP,php,session,session-cookies,Php,Session,Session Cookies,我有一个登录页面,加载后会显示一个登录对话框。登录对话框只是一个使用Ajax调用的JQuery对话框。诸如此类: $(function() { var _width = $.browser.msie ? 316 : 'auto'; var loginDialog = $('#loginDialog'); loginDialog.dialog({ closeOnEscape: false, open: function() {

我有一个登录页面,加载后会显示一个登录对话框。登录对话框只是一个使用
Ajax调用的
JQuery
对话框。诸如此类:

$(function() {
    var _width = $.browser.msie ? 316 : 'auto';
    var loginDialog = $('#loginDialog');

    loginDialog.dialog({
        closeOnEscape: false,
        open: function() {
            $(this).parent().find('.ui-dialog-titlebar-close').hide();
        },
        resizable: false,
        position: 'center',
        stack: true,
        draggable: false,
        height: 'auto',
        width: _width,
        modal: true,
        buttons: {
            'submit': function() {
                $.ajax({
                type: 'post',
                dataType: 'html',
                url: '/ProjectName/Scripts/php/AccountController.php',
                cache: false,
                // async: false,
                data: $('#loginForm').serialize(),
                success: function(accessStatus) {
                    if(accessStatus === 'granted') {
                        loginDialog.dialog('close');
                    }
                },
                error: function(request, status, error) {
                    // handle it in a specific manner
                    alert(error);
                }
            });
        }
    }        
});
<?php   
    session_start();
    if(IsAjaxRequest()) {
        if(isset($_REQUEST['username']) && isset($_REQUEST['password'])) {  
            require_once('LDAPHandler.php');

            // credentials
            $username = $_REQUEST['username'];
            $password = $_REQUEST['password'];
            // ... more parameters

            // ... Fetch against AD
            if(IsInAdminRole($username, $password)) {
                // ... establishing mysql connection & setting connection options

                // and then:                        
                mysql_query(
                    'insert into accounts'. 
                    '(login, sid) values({$username}, {session_id()})'.
                    'on duplicate key update sid=values(sid)'
                );

                // write response
                echo 'granted';
            }
        }
    }
?>
因此,如果可以(在服务器端),我只需关闭对话框

然后在
AccountController.php
文件中,现在我有如下内容:

$(function() {
    var _width = $.browser.msie ? 316 : 'auto';
    var loginDialog = $('#loginDialog');

    loginDialog.dialog({
        closeOnEscape: false,
        open: function() {
            $(this).parent().find('.ui-dialog-titlebar-close').hide();
        },
        resizable: false,
        position: 'center',
        stack: true,
        draggable: false,
        height: 'auto',
        width: _width,
        modal: true,
        buttons: {
            'submit': function() {
                $.ajax({
                type: 'post',
                dataType: 'html',
                url: '/ProjectName/Scripts/php/AccountController.php',
                cache: false,
                // async: false,
                data: $('#loginForm').serialize(),
                success: function(accessStatus) {
                    if(accessStatus === 'granted') {
                        loginDialog.dialog('close');
                    }
                },
                error: function(request, status, error) {
                    // handle it in a specific manner
                    alert(error);
                }
            });
        }
    }        
});
<?php   
    session_start();
    if(IsAjaxRequest()) {
        if(isset($_REQUEST['username']) && isset($_REQUEST['password'])) {  
            require_once('LDAPHandler.php');

            // credentials
            $username = $_REQUEST['username'];
            $password = $_REQUEST['password'];
            // ... more parameters

            // ... Fetch against AD
            if(IsInAdminRole($username, $password)) {
                // ... establishing mysql connection & setting connection options

                // and then:                        
                mysql_query(
                    'insert into accounts'. 
                    '(login, sid) values({$username}, {session_id()})'.
                    'on duplicate key update sid=values(sid)'
                );

                // write response
                echo 'granted';
            }
        }
    }
?>

我想要的是在数据库中的相关记录(
Accounts表
)中存储
sid
。让我困惑的是:

  • 据我所知,如果用户在成功登录后复制某些页面,服务器将使用相同的会话cookie?我说得对吗?除非浏览器关闭
  • 我如何处理不同浏览器的情况
  • 我读到,无论我在哪里需要使用会话,我都必须调用页面上的
    session\u start()
    。这是否会给出一个与登录时编写的sid不同的sid
  • 比如说,如果我不想重复,我的意思是用户不应该多次(同时)访问同一资源,哪种方式是最好的处理方法
  • 另外,我知道我需要使用某种标志(可能是accounts表中的字段)来表示用户处于活动状态,因为以其他方式,我将只存储最后一个
    sid
    。或者更好的解决方案是在会话关闭后从数据库中删除用户
非常感谢

  • 是的,你是对的(除非客户端有篡改)
  • 你为什么要担心这个
  • session\u start()
    将启动一个新会话,如果以前启动过,则恢复上一个会话
  • 相信我,不要尝试
  • 这有助于查看现在登录的用户,但当用户注销或他/她有一段时间没有处于活动状态时(15分钟是合理的),必须将“活动”设置为0
更新:这些与您的问题没有直接关系,但最好记住它们

  • 您的代码(SQL部分)易受攻击,请阅读此内容以了解如何保护您自己

  • 当提供空(或NUL)密码时,您的LDAP代码容易受到误报身份验证的攻击,因为
    LDAP\u bind()
    将在未提供密码的情况下尝试,这将导致任何人在提供正确用户名的情况下登录。所以,请确保过滤掉所有控制字符,然后检查空密码

  • 通过提供
    *
    作为用户名,还可以对代码执行LDAP“注入”


出于好奇,您的
LDAPHandler.php
是否使用php的本机
ldap_bind()
?是的,我使用的是本机ldap_bind();我还没有为此感到后悔)如果您共享
LDAPHandler.php
的代码可以吗?(特别是关于
ldap\u bind()
的部分。当然,在去掉个人信息之后。我一直在研究一些不好的实践案例,我非常好奇。当然我可以分享ldap代码,但如果我把它放在问题中,它会很混乱)给你哦!这是伟大的,我真的很感激!我也很好奇如何截获会话关闭事件并处理它。