【问题标题】:Getting user info through itsdangerous token通过其危险令牌获取用户信息
【发布时间】:2016-03-15 20:56:20
【问题描述】:

我目前正在通过 Miguel Grinberg 的书学习 Flask。如果你熟悉你可能知道Flasky(Miguel 在本书中使用的一个应用程序)

我目前在第 8 节,处理密码重置,这里是 原始代码(您也可以在 repo 上找到它。它的标签是 8g):

models.py

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    ...
    def generate_reset_token(self, expiration=3600):
        s = Serializer(current_app.config['SECRET_KEY'], expiration)
        return s.dumps({'reset': self.id})

    def reset_password(self, token, new_password):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            return False
        if data.get('reset') != self.id:
            return False
        self.password = new_password
        db.session.add(self)
        return True

auth/views.py

@auth.route('/reset/<token>', methods=['GET', 'POST'])
def password_reset(token):
    if not current_user.is_anonymous:
        return redirect(url_for('main.index'))
    form = PasswordResetForm()
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user is None:
            return redirect(url_for('main.index'))
        if user.reset_password(token, form.password.data):
            flash('Your password has been updated.')
            return redirect(url_for('auth.login'))
        else:
            return redirect(url_for('main.index'))
    return render_template('auth/reset_password.html', form=form)

auth/forms.py

class PasswordResetForm(Form):
    email = StringField('Email', validators=[Required(), Length(1, 64),
                                             Email()])
    password = PasswordField('New Password', validators=[
        Required(), EqualTo('password2', message='Passwords must match')])
    password2 = PasswordField('Confirm password', validators=[Required()])
    submit = SubmitField('Reset Password')

    def validate_email(self, field):
        if User.query.filter_by(email=field.data).first() is None:
            raise ValidationError('Unknown email address.')

我的问题:

我不想再次询问用户他们的电子邮件,因为他们正在通过他们收到的电子邮件更改密码。有没有办法从该令牌中获取用户或用户的电子邮件?

【问题讨论】:

    标签: python flask token


    【解决方案1】:

    对于 1- 在安全级别上,隐藏谁在您的网站上拥有帐户对您的用户来说是一个很好的优势。例如,假设它是一个 Addicts Anonymous 网站,如果我想查看 alice@example.com 是否是会员,我可以简单地尝试重置密码以确认她是会员。

    或者,如果您有大量电子邮件地址,则可以使用该密码重置表单将列表范围缩小到活跃成员,以用于更有针对性的社会工程攻击,或者至少缩小列表范围(如果您是旨在暴力破解他们。

    【讨论】:

    • 哦好吧,既然你提到了,那就是真的!没想到
    • 我已经改变了整个问题,你知道怎么做吗?
    【解决方案2】:

    好吧,以防万一这对其他人有用。用户信息已经在令牌中,在 {'reset': user_id} 中。

    问题是令牌管理逻辑在用户模型中。因此,在表单中有一个电子邮件字段以便以后在视图中找到该用户在当前版本中可以解决问题

    由于您在此视图中获得了令牌,我们可以将该逻辑移至视图:

    auth/views.py

    from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
    
    @auth.route('/reset/<token>', methods=['GET', 'POST'])
    def reset_password(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except:
            raise ValidationError()
        user_id = data['reset']
        ....
    

    而在User模型中,我们需要修改reset_password()方法:

    models.py

    class User(UserMixin, db.Model):
        __tablename__ = 'users'
    
        ...
    
        def reset_password(self, new_password):
            self.password = new_password
            db.session.add(self)
            return True
    

    【讨论】:

      猜你喜欢
      • 2016-08-07
      • 1970-01-01
      • 1970-01-01
      • 2015-07-12
      • 2015-08-18
      • 1970-01-01
      • 2020-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多