使用ajax间歇性地烧录登录问题

时间:2016-02-18 23:43:03

标签: python ajax flask flask-login

我使用Ajax登录,使用Flask-Login扩展。这是我的服务器端代码:

@app.route('/login', methods=["POST"])
def login():
    if current_user.is_authenticated:
        redirect_url = url_for('index')
        return jsonify(loggedIn=True, redirectUrl=redirect_url)

    username = request.form.get('username', '').strip()
    password = request.form.get('password', '').strip()
    user = User.query.filter_by(username=username).first()
    if user and util.encrypt_password(password, user.salt) == user.password:
        logged_in_user = CurrentUser(user)
        login_user(logged_in_user)
        redirect_url = url_for('index')
        return jsonify(loggedIn=True, redirectUrl=redirect_url)
    else:   
        return jsonify(loggedIn=False, error='Invalid Email/Password')

和我的客户端代码:

(function(){
        $login_form = $('#login_form');

        //add validation to form
        if( $login_form.length ){

            $login_form.parsley()
            $login_form.submit(function(e) {
                var url = $(this).attr('action');
                var data = $(this).serialize();

                tryLogin(url, data);
                return false;
            }); 
        }

       function tryLogin(url, data){
        var $submitBtn = $('#login_form__submit');

        //notify user that we are working
        $submitBtn.addClass('btn--loading');

        $.ajax({
            type: 'POST',
            url: url,
            data: data,
            dataType: 'json',
            success: function (data) {
                if (data.loggedIn) {
                    mixpanel.track('login_success');
                    window.location.href = data.redirectUrl || '/';
                } 
             }
         });
      }
});

不确定是什么问题,我最近开始看到这个问题,并且失败的次数超过50%。如果失败,它只会重定向到新页面,但不存在会话信息。所有内容都托管在同一个域中。

修改 更多信息:即使登录间歇性地工作,后端也会通过登录,前端会收到loggedIn=TrueredirectUrl。似乎问题是客户端收到会话/ cookie但不确定为什么会出现间歇性问题。

更新

Wholever现在正在读这个。我无法找到一个好的解决方案。但调试并意识到这肯定是因为Chrome中的一些错误来更新Ajax请求中的cookie /会话数据。 我通过使用redis而不是客户端转移到服务器端会话来解决这个问题。这确保了请求始终具有正确的会话信息。

4 个答案:

答案 0 :(得分:2)

默认情况下,Flask中的URL路由器仅响应GET方法。您正在使用POST方法在AJAX中发出请求。

看起来您的查看功能应该同时处理GETPOST(当登录用户访问此网址时,只需重定向到index页面?)

因此,您必须明确将methods参数设置为@app.route,更改此行

@app.route('/login')

为:

@app.route('/login', methods=['GET', 'POST'])

再试一次。

如果不能正常工作,请发表评论,我会不断更新。

答案 1 :(得分:2)

您可以修改代码以使用werkzeug库吗?

除非你的util有check_password方法。在内部,create hash方法可以为每次调用返回相同salt的不同密码哈希值。这解释了间歇性问题,因为有时返回的哈希匹配,有时它不会。我相信这一切都取决于随机函数,它通常与时钟和内部散列算法有关。

Theres不需要使用werkzeug存储密码哈希,因为它存储在哈希本身并已加盐。我自己使用了werkzeug库进行登录,下面的代码应该可以使用。前提是您使用werkzeug提供的generate_password_hash生成密码哈希和存储而不是数据库。 Werkzeug library

您的代码使用werkzeug:

from werkzeug.security import generate_password_hash, \
     check_password_hash
@app.route('/login', methods=["POST"])
def login():
    if current_user.is_authenticated:
        redirect_url = url_for('index')
        return jsonify(loggedIn=True, redirectUrl=redirect_url)

    username = request.form.get('username', '').strip()
    password = request.form.get('password', '').strip()
    user = User.query.filter_by(username=username).first()
    if user and check_password_hash(user.password, password):
        logged_in_user = CurrentUser(user)
        login_user(logged_in_user)
        redirect_url = url_for('index')
        return jsonify(loggedIn=True, redirectUrl=redirect_url)
    else:   
        return jsonify(loggedIn=False, error='Invalid Email/Password')

控制台的一个例子:

>>> from werkzeug.security import generate_password_hash, check_password_hash
>>> password = 'cat'
>>> a = generate_password_hash(password)
>>> b = generate_password_hash(password)
>>> c = generate_password_hash(password)
>>> for i in (a, b, c):
...   print i
...
pbkdf2:sha1:1000$NdpMiLKu$7c24f73766856ac94102733ae9bf93c0f79b5e53
pbkdf2:sha1:1000$dh2mj93K$61103a04a1bcb16e95a44ca3615518b12fecafc1
pbkdf2:sha1:1000$wdGPkX4p$9db55c5035e9c71f7e1e14ece6be619bf9fdaccf
>>> for i in (a, b, c):
...   print check_password_hash(i, password)
...
True
True
True
>>> print check_password_hash(a, 'dog')
False

答案 2 :(得分:0)

尝试检查它不是与在Ajax请求中使用cookie相关的jQuery错误:https://stackoverflow.com/a/7189502/882187

此外,尝试在短暂超时后进行重定向,以确保它发生在ajax回调处理程序之外。由于JS中的回调,这个问题可能是间歇性的。如果使用'window.location.href'重定向会破坏cookie处理处理程序,那该怎么办?

答案 3 :(得分:0)

我遇到的问题是,如果我通过AJAX发出过帐请求,“烧瓶登录”将无法登录,但是如果我发出GET请求或从表单过帐,则可以使用。原来,我发布到的URL是http://0.0.0.0:8000/ ...而不是http://localhost:8000/ ...。将网址更改为http://localhost:8000/可以解决我的问题。