0

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

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 添加任何内容。这就是Providerdb.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

为了实现基本身份验证,Provider具有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

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

@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"'})
...
4

1 回答 1

1

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

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

此外,如果 Provider 应用程序将在不同的域上运行,请记住浏览器对Ajax 请求施加相同的来源策略。在这种情况下,您需要实现JSONPCORS

于 2013-03-18T15:54:21.433 回答