管理员(仅限)注册用户,Flask安全

2024-10-01 09:27:15 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在使用Flask Security(包括Flask WTForms、Flask SQLalchemy和Flask login)为webapp构建一个登录。我已经能够相当轻松地设置我的大部分登录流,包括忘记的密码;但是我想让它成为用户注册的唯一方式是通过一个只有管理员可以访问的页面。我已经成功地配置了角色(管理员、用户)并设置了以下视图:

@app.route('/adminregister')
@roles_accepted('admin')
def adminregister():
    return render_template('*')

这将创建成功限制为具有管理员角色的帐户的门户。不过,我不确定如何继续进行,因为Flask security没有内置的方法来实现我正在尝试的操作。在

我已经重写RegisterForm以通过regexp强制执行密码规则:

^{pr2}$

基本上,我想要一个位于/adminregister的表单,当管理员访问时允许输入电子邮件地址,此时首先在数据库中创建一个随机和安全的密码,然后发生类似于忘记密码的过程,并创建一个1次密码代码来重置密码。在

我看过的有用的东西:

  1. 烧瓶内安全/视图.py这里有一个被遗忘的密码:

    def forgot_password():
    """View function that handles a forgotten password request."""
    
    form_class = _security.forgot_password_form
    
    if request.json:
        form = form_class(MultiDict(request.json))
    else:
        form = form_class()
    
    if form.validate_on_submit():
        send_reset_password_instructions(form.user)
        if request.json is None:
            do_flash(*get_message('PASSWORD_RESET_REQUEST', email=form.user.email))
    
    if request.json:
        return _render_json(form, include_user=False)
    
    return _security.render_template(config_value('FORGOT_PASSWORD_TEMPLATE'),
                                 forgot_password_form=form,
                                 **_ctx('forgot_password'))
    
  2. 在flask_security内/可注册.py有注册用户的代码

    def register_user(**kwargs):
    confirmation_link, token = None, None
    kwargs['password'] = encrypt_password(kwargs['password'])
    user = _datastore.create_user(**kwargs)
    _datastore.commit()
    
    if _security.confirmable:
        confirmation_link, token = generate_confirmation_link(user)
        do_flash(*get_message('CONFIRM_REGISTRATION', email=user.email))
    
    user_registered.send(app._get_current_object(),
                         user=user, confirm_token=token)
    
    if config_value('SEND_REGISTER_EMAIL'):
        send_mail(config_value('EMAIL_SUBJECT_REGISTER'), user.email, 'welcome',
                  user=user, confirmation_link=confirmation_link)
    
    return user
    

我想以某种方式将这两者结合起来,这样在提交一个只有“Email”字段的表单时,'/adminregister'会在数据库中添加一个安全的、随机的密码,电子邮件地址会被发送一封带有更改密码链接的电子邮件(最好是一条解释密码的消息)。我甚至不知道应该在哪里添加这样的代码,因为没有什么可以特别重写的,尤其是我找不到一种方法来覆盖RegisterForm,使其具有更少的字段和相同的功能。在

我的代码结构与flask安全文档的quickstart一致。在

提前感谢您提供的任何指导。在


Tags: formjson密码flaskreturnifemailrequest
3条回答

寄存器过程创建一个带有闪烁器的信号,您可以这样访问:

from flask.ext.security.signals import user_registered
@user_registered.connect_via(app)
def user_registered_sighandler(app, user, confirm_token):
    user_datastore.deactivate_user(user)
    db.session.commit()

这将停用任何新注册的用户。在

我知道这是一个古老的问题,但我想我有一个优雅的答案。在

第一个导入寄存器用户

from flask_security.registerable import register_user

然后,由于您不想让任何人注册,请确保registerable被禁用(尽管disabled是默认设置,因此您可以忽略此设置),并且由于您希望发送确认电子邮件,请启用confirmable和changeable,以便用户更改密码

^{pr2}$

然后,您可以创建用户注册视图,并用role required装饰它。我使用了我自己的自定义注册表,所以我不得不多走一英里去检查用户是否已经存在,并返回一个相应的错误

@app.route('/admin/create/user', methods=['GET', 'POST'])
@roles_required('admin')
def admin_create_user():
    form = RegistrationForm(request.form)
    if request.method == 'POST' and form.validate_on_submit():
        email = form.email.data
        password = form.password.data
        user_exists = session.query(User).filter_by(email=email).first()
        if user_exists:
            form.email.errors.append(email + ' is already associated with another user')
            form.email.data = email
            email = ''
            return render_template('create-user.html', form = form)

        else:
            register_user(
                    email=email,
                    password = password)
            flash('User added successfully')
            return render_template('create-user.html', form = form)

最后,我使用了如下解决方法:

  1. 我启用了注册,但将注册视图限制为具有管理员角色的用户。

  2. 我在views->;register中使用了del form.password,不再发送带有密码字段的表单。

  3. 我在.registerable中执行了以下操作,生成一个随机密码来填充表。在

    kwargs['password'] = encrypt_password(os.urandom(24))

  4. 当管理员在注册表中输入一封电子邮件时,我已经启用了configible。这意味着用户将立即收到一封电子邮件,确认他们的帐户,并解释他们已经注册。确认后,他们会被重定向到忘记密码页面,并要求更改他们的密码(这是基于安全性的限制)。

如果有人能想出更直接的方法,我会很感激的。我把这个留在这里以防有人有同样的问题。在

相关问题 更多 >