Issue
Forgive my naivety here, but I've been looking into various solutions for role authentication in Flask, and it seems that several extensions are no longer being maintained. This got me wondering whether I require any of them beyond Flask Login for my purposes.
Is it sufficient to use if current_user.is_admin
in my routes and templates to distinguish between admins and other users? If so, are there any security concerns or other drawbacks to consider with this approach vs using something like Flask Security Too? I'm realizing this approach would get very repetitive - could I create a decorator to perform this check? I don't have a solid handle on decorators yet.
routes.py
@app.route('/students', methods=['GET', 'POST'])
@login_required
def students():
form = StudentForm()
if current_user.is_admin:
if form.validate_on_submit():
student = Student(student_name=form.student_name.data, last_name=form.last_name.data, \
student_email=form.student_email.data, parent_name=form.parent_name.data, \
parent_email=form.parent_email.data, secondary_email=form.secondary_email.data, \
timezone=form.timezone.data, location=form.location.data, status=form.status.data, \
tutor=form.tutor_id.data)
try:
db.session.add(student)
db.session.commit()
except:
db.session.rollback()
flash(student.student_name + ' could not be added', 'error')
return redirect(url_for('students'))
flash(student.student_name + ' added')
return redirect(url_for('students'))
return render_template('students.html', title="Students", form=form)
else:
flash('You must have administrator privileges to access this page.', 'error')
logout_user()
return redirect(url_for('login'))
models.py
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
...
is_admin = db.Column(db.Boolean)
Solution
Created the following admin_required
decorator:
def admin_required(f):
@login_required
@wraps(f)
def wrap(*args, **kwargs):
if current_user.is_admin:
return f(*args, **kwargs)
else:
flash('You must have administrator privileges to access this page.', 'error')
logout_user()
return redirect(login_url('login', next_url=request.url))
return wrap
Note it is important to validate next_url
in your login view to avoid phishy redirects:
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
...
next = request.args.get('next')
if not next or url_parse(next).netloc != '':
next = url_for('default_redirect')
return redirect(next)
return render_template('login.html', title="Login", form=form)
Answered By - dannypernik
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.