0

我正在创建一个项目,我想使用 Flask_Principal 限制用户的访问?

我正在研究那个,所以...我知道关于那些微框架的事情。

基本上......用户将访问主页,如果他没有登录,他需要进行注册。之后,程序将他发送到登录页面。然后,他需要登录才能访问包含特定消息的主页。

通过登录访问,在主页中,带有特定消息,用户可以单击三个链接(主页、注销、欢迎)。

现在,那是我的问题。我想为某些无法访问“欢迎”链接的用户创建限制访问权限。如何使用 Flask-Principal 执行此操作?

这是我的 app.py

from projeto import app, db
from flask import Blueprint, render_template, redirect, request, url_for
from flask_login import login_user, login_required, logout_user
from projeto.models import User
from projeto.forms import LoginForm, RegistrationForm


@app.route('/')
def home():
    return render_template('home.html')


@app.route('/welcome')
@login_required
def welcome_user():
    return render_template('welcome_user.html')


@app.route('/logout')
@login_required
def logout():
    logout_user()
    #flash('Logout realizado com sucesso!')
    return redirect(url_for('home'))


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

    form = LoginForm()
    #if form.validate_on_submit():
    if form.validate_on_submit():
        # Grab the user from our User Models table

        user = User.query.filter_by(email=form.email.data).first()
        if user is None or user.password != form.password.data:
            return redirect(url_for('login'))
        #if user.email == form.email.data and user.password == form.password.data:
            #return redirect(url_for('home'))
        login_user(user)
        return redirect(url_for('home'))
    return render_template('login.html', form=form)


@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegistrationForm()

    if request.method == 'POST':
        user = User(name=form.name.data,
                    address=form.address.data,
                    number=form.number.data,
                    city=form.city.data,
                    state=form.state.data,
                    country_code=form.country_code.data,
                    phone=form.phone.data,
                    email=form.email.data,
                    username=form.username.data,
                    password=form.password.data,
                    #pass_confirm=form.pass_confirm.data
                    pass_confirm=form.password.data)

        db.session.add(user)
        db.session.commit()
        return redirect(url_for('login'))
    return render_template('register.html', form=form)


if __name__ == '__main__':
    app.run(debug=True)

这是我的初始化.py

    import os
    from flask import Flask, Blueprint
    from flask_sqlalchemy import SQLAlchemy
    from flask_migrate import Migrate
    from flask_login import LoginManager
    
    #CREATE A LOGIN MANAGER OBJECT
    login_manager = LoginManager()
    
    #CREATE MY APPLICATION
    app = Flask(__name__)
    
    # CREATE MY DATABASE
    app.config['SECRET_KEY'] = 'secret'
    basedir = os.path.abspath(os.path.dirname(__file__))
    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    
    #CONFIGURATE MY DATABASE WITH THE APP STRUCTURE
    db = SQLAlchemy(app)
    Migrate(app,db)
    
    #Pass in our app to the login MANAGER
    login_manager.init_app(app)
    
    # Tell users what view to go when they need to login_manager
    login_manager.login_view = 'login'

这是我的forms.py

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, IntegerField
from wtforms.validators import DataRequired, Email, EqualTo, NumberRange
from wtforms import ValidationError

class LoginForm(FlaskForm):
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Senha', validators=[DataRequired()])
    submit = SubmitField('Log in')

class RegistrationForm(FlaskForm):
    name = StringField('Nome completo', validators=[DataRequired()])
    address = StringField('Rua', validators=[DataRequired()])
    number = IntegerField('Número', validators=[DataRequired()])
    city = StringField('Cidade', validators=[DataRequired()])
    state = StringField('Estado', validators=[DataRequired()])
    country_code = IntegerField('CEP', validators=[DataRequired()])
    phone = IntegerField('Telefone', validators=[NumberRange(min=0, max=11)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    username = StringField('Usuário', validators=[DataRequired()])
    password = PasswordField('Senha', validators=[DataRequired(), EqualTo('pass_confirm', message = 'Passwords Must Match')])
    pass_confirm = PasswordField('Confirme sua senha', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('Cadastrar')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)


    def check_email(self, field):
        # Check if not None for that user email!
        if User.query.filter_by(email=field.data).first():
            raise ValidationError('Este e-mail já foi registrado por um outro usuário!')


    def check_username(self, field):
        #Check if not None for name!
        if User.query.filter_by(usernname=field.data).first():
            raise ValidationError('Este usuário já existe.')


    def check_name(self, field):
        # Check if not None for that username!
        if User.query.filter_by(name=field.data).first():
            raise ValidationError('Este nome já foi registrado anteriormente.')

这是我的models.py

from projeto import db, login_manager
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin


@login_manager.user_loader
def load_user(user_id):
    return User.query.get(user_id)

class User(db.Model, UserMixin):

    # Create a table in the db
    __tablename__ = 'usuario'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(70))
    address = db.Column(db.String(120))
    number = db.Column(db.Integer)
    city = db.Column(db.String(150))
    state = db.Column(db.String(20))
    country_code = db.Column(db.Integer)
    phone = db.Column(db.String(11))
    email =db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    password = db.Column(db.String(128))
    pass_confirm = db.Column(db.String(128))

    def __init__(self, name, address, number, city, state, country_code, phone,
                email, username, password, pass_confirm):

        self.name = name
        self.address = address
        self.number = number
        self.city = city
        self.state = state
        self.country_code = country_code
        self.phone = phone
        self.email = email
        self.username = username
        self.password = password
        self.pass_confirm = pass_confirm

这是我的 base.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-eOJMYsd53ii+scO/bJGFsiCZc+5NDVN2yr8+0RDqr0Ql0h+rP48ckxlpbzKgwra6" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta3/dist/js/bootstrap.bundle.min.js" integrity="sha384-JEW9xMcG8R+pH31jmWH6WWP0WintQrMb4s7ZOdauHnUtxwoG2vI5DkLtS3qm9Ekf" crossorigin="anonymous"></script>
    <meta charset="utf-8">
    <title>Projeto Voluntário - DOJO</title>
  </head>
  <body>

<nav class="navbar navbar-expand-lg navbar-light bg-light">
    <ul class="nav">
      <li class="nav-item">
    <a class="nav-link" href="{{ url_for('home') }}">Página Inicial</a>
  </li>
    {% if current_user.is_authenticated %}
    <li class="nav-link"><a href="{{ url_for('logout') }}">Log Out</a></li>
    <li class="nav-link"><a href="{{ url_for('welcome_user') }}">Welcome</a></li>
    {% else %}
    <li class="nav-link"><a href="{{ url_for('register') }}">Cadastro</a></li>
    <li class="nav-link"><a href="{{ url_for('login') }}">Log In</a></li>

      {%endif%}
    </ul>
    <form class="d-flex">
        <input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
        <button class="btn btn-outline-success" type="submit">Buscar</button>
    </form>
</nav>
    {% block content %}

    {% endblock %}


  </body>
</html>

如果有人可以帮助我,我将不胜感激。

4

1 回答 1

0

不完全确定你在问什么。首先 - 您的问题询问 Flask_Principle 和 Flask-Security - 但您没有使用 Flask-Security - 其中包含注册、登录等视图。Flask-Security 还包含“角色”——它们建立在 Flask-Principle 之上,提供比“身份验证”更精细的访问控制。

所以 - 这是你的问题吗?用户注册并登录(验证)后,您希望更精细地访问各种 API 端点吗?如果是这样 - 那么 Flask-Security 可能就是您正在寻找的。

于 2021-05-20T00:14:53.017 回答