jQuery-Ajax调用基本身份验证失败

时间:2013-03-18 15:22:04

标签: jquery web2py

我有2个Web2Py应用程序,让我称之为 Provider Receiver Provider 提供基本身份验证功能, Receiver 使用它来登录。用户已在 Provider Receiver的本地数据库中创建使用这些用户凭据成功登录。但是当我在我的控制器中使用RESTful方法时,如果我使用相同的用户名通过相同的浏览器会话手动登录到 Provider ,则jQuery-Ajax调用只能起作用。如果我不这样做并且只从 Receiver 登录,则表示已成功登录,但未成功执行Ajax GET调用。如果我使用一个用户名登录 Reciever ,使用其他用户名登录 Provider ,则Ajax GET会提取登录到 Provider 的用户的信息。我把它作为脚本放在 Receiver index.html中:

var gBaseUrl="http://127.0.0.1:8000/Provider/sites/";
$(document).ready(function(){
  $.ajax({
      type: "GET",
      async: true,
      url: gBaseUrl+"get_username",
      dataType: "text",
      success: function(data){
        $('#ContentView').append('<p> succeeded '+data+'</p>');
      }
      failure: function(data){
        $('#ContentView').append('<p> failed '+data+'</p>');
      }
    });
});

如果我未在本地登录 Provider ,则不会向ContentView添加任何内容。这就是 Provider db.py的样子:

## configure auth policy
auth.settings.registration_requires_verification = True
auth.settings.registration_requires_approval = True
auth.settings.reset_password_requires_verification = True
auth.settings.allow_basic_login = True
auth.settings.controller = 'default'
auth.settings.hmac_key = None
auth.settings.mailer = None
auth.settings.login_after_registration = False

要实现基本身份验证,提供商default.py具有以下功能:

def basic_auth():
    """
    checks if the user is logged in and returns True/False.
    if so user is in auth.user as well as in session.auth.user
    """
    auth.basic()
    if auth.user:
        print("login success!")
        print(auth.user.username, " is logging in!")
        session.forget()
        return True
    else:
        print("login failed!")
        return False

然后返回用户名,在 Provider site控制器中,我有:

@request.restful()
@auth.requires_login()
def get_username():
    def GET():
        return str(auth.user.username)
    return locals()

ContentView只是我在div中的空index.html

我还在requires中稍微修改了gluon/tools.py装饰器的实现:

if current.request.ajax:
    raise HTTP(401)
...
elif self.settings.allow_basic_login_only or \
        basic_accepted or current.request.is_restful:
    raise HTTP(401, **{'WWW-Authenticate': 'Basic realm="My Realm"'})
...

1 个答案:

答案 0 :(得分:1)

如果要通过基本身份验证登录,则需要在请求的HTTP头中提供登录凭据,而Ajax代码不会这样做。无论如何,更好的选择可能是使用内置的Central Authentication Service功能。由于您是从浏览器发出Ajax请求,因此会话cookie将随请求一起发送,因此没有理由将自己限制为基本身份验证。

更新:如果您需要使用基本身份验证,请注意jQuery .ajax()方法需要usernamepassword个参数。它还允许您直接设置标题。您还可以让服务器发送401响应并让浏览器处理凭据提示,但这不是最好的用户体验。

此外,如果Provider应用程序将在其他域上运行,请记住浏览器对Ajax请求强制same origin policy。在这种情况下,您需要实施JSONPCORS