0

我有一个登录页面,一旦加载就会显示登录对话框。登录对话框只是一个JQuery使用Ajax call. 像这样的东西:

$(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);
                }
            });
        }
    }        
});

因此,如果可以(在服务器端),我只需关闭对话框。

然后在AccountController.php文件中,我现在有类似的东西:

<?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';
            }
        }
    }
?>

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

  • 据我了解,如果用户在成功登录服务器后复制某些页面将使用相同的会话 cookie?我对吗?除非浏览器关闭。
  • 我如何处理不同浏览器的情况?
  • 我读到,无论我需要在哪里使用我必须session_start()在页面上调用的会话。这不会sid与登录期间编写的不同吗?
  • 假设我不想重复,我的意思是用户不应该多次(同时)访问同一个资源,哪种方式是最好的处理方式?
  • 另外我知道我需要使用某种标志(可能是帐户表中的字段)来表示 user 是active,因为以其他方式我将只存储最后一个sid。或者更好的解决方案是在会话关闭后从数据库中删除用户?

非常感谢!!

4

1 回答 1

1
  • Yes you're right (unless there's some tampering on the client-side).
  • Why do you need to worry about that?
  • session_start() will start a new session and resume a previous one if started before.
  • Trust me, don't try.
  • This is good to see who's logged in now, but you have to set active to 0 when the user logs out or when he/she hasn't been active for a while (15 minutes is reasonable).

Update: Those aren't directly related to your question, but it's good to keep them in mind.

  • You're code (SQL part) is vulnerable to SQL Injection, please read this answer here to learn how to protect yourself.

  • Your LDAP code is vulnerable to false-positive authentication when an empty (or NUL) password is provided, because ldap_bind() will attempt anonymous binding if no password was provided, which will result in anyone logging in if they provide the correct username. So make sure you filter out all control characters and then check for empty password.

  • It's also possible to perform LDAP "injection" to your code by providing * as a username.

于 2012-07-17T08:48:47.903 回答