@89109983838

Как «прикрутить» простую авторизацию к flask-admin?

Доброе время суток!
Осваиваю flask-admin, в данный момент для авторизации использую чуть поправленный "под себя" пакет https://github.com/MrJoes/Flask-Admin/tree/master/...
Но возникла необходимость сделать авторизацию без использования базы данных, по средствам хранения логина и пароля в файле конфигурации приложения (т.к. пользователь будет только один)... вот и ломаю голову как прикрутить простейший вариант по примеру из манов flask-russian-docs.readthedocs.org/ru/latest/tutor...

подскажите как выше указанный простенький пример правильно внедрить в is_accessible вместо login.current_user.is_authenticated()
class MyView(BaseView):
    def is_accessible(self):
        return login.current_user.is_authenticated()
  • Вопрос задан
  • 6050 просмотров
Решения вопроса 1
@89109983838 Автор вопроса
проблема решена _ решение в самом низу поста! ;)))

Попробовал реализовать! переправив код авторизации через базу данных на аккаунт из конфига.

проверка проходит!
далее при правельном акаунте выходит Traceback
jinja2.exceptions.UndefinedError
UndefinedError: 'form' is undefined


File "..........\app\templates\admin\index.html", line 17, in block "body"
........

17 {{ form.hidden_tag() if form.hidden_tag }} <----- на это ругается
18 {% for f in form if f.type != 'CSRFTokenField' %}
19
.......

Основной код по этой ситуации:
# -*- coding: utf-8 -*-
import os
from flask import Flask, request, session, g, redirect, url_for, abort, render_template, flash
from flask.ext.sqlalchemy import SQLAlchemy
from wtforms import form, fields, validators
from flask.ext import admin
from flask.ext.admin.contrib import sqla
from flask.ext.admin import helpers, expose



# Create Flask application
app = Flask(__name__)

# Create dummy secrey key so we can use sessions
app.config['CSRF_ENABLED'] = True
app.config['SECRET_KEY'] = '12345678290244'
#app.config['DEBUG'] = 'True'
app.config['USERNAME'] = 'admin'
app.config['PASSWORD'] = '1234'


# Create in-memory database (база для примера, для авторизации не используется)
app.config['DATABASE_FILE'] = 'db.sqlite'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + app.config['DATABASE_FILE']
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)


# Create user model (модель для примера, для авторизации не используется).
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String(100))
    last_name = db.Column(db.String(100))
    login = db.Column(db.String(80), unique=True)
    email = db.Column(db.String(120))
    password = db.Column(db.String(64))
   # Отображение в административном интерфейсе
    def __unicode__(self):
        return self.username

# Define login and registration forms
class LoginForm(form.Form):
    login = fields.TextField(validators=[validators.required()])
    password = fields.PasswordField(validators=[validators.required()])

    def validate_login(self, field):
        
        if app.config['USERNAME'] != self.login.data:
            raise validators.ValidationError('Invalid user')

        if app.config['PASSWORD'] != self.password.data:
            raise validators.ValidationError('Invalid password')
    # присудствовало в оригинальном файле при хранение акаунта в базе данных         
    #def get_user(self):
    #    return db.session.query(User).filter_by(login=self.login.data).first()

def logged_in():
    # в сессии будет храниться информация о том, что пользователь вошёл
    return session.get('logged')
        
# Create customized model view class
class MyModelView(sqla.ModelView):

    def is_accessible(self):
        return logged_in()
    
    def _handle_view(self, name, **kwargs):
        if not logged_in():
            # делать редирект в некоторых случаях не стоит
            return redirect(url_for('.login_view'))


# Create customized index view class that handles login & registration
class MyAdminIndexView(admin.AdminIndexView):

    @expose('/')
    def index(self):
        if not logged_in():
            return redirect(url_for('.login_view'))
        return super(MyAdminIndexView, self).index()

    @expose('/login/', methods=('GET', 'POST'))
    def login_view(self):
        # handle user login
        form = LoginForm(request.form)
        if helpers.validate_form_on_submit(form):
            #использовалось в оригинальном фале при авторизацию через базу данных
            #user = form.get_user()
            #login.login_user(user)
            session.update({'logged':True}) # возможно задаю не правильно, подправте если не так!
            session.modified = True

        if logged_in():
            return redirect(url_for('.index'))
        link = '<p>Don\'t have an account? <a href="' + url_for('.register_view') + '">Click here to register.</a></p>'
        self._template_args['form'] = form
        self._template_args['link'] = link
        return super(MyAdminIndexView, self).index()
  
    @expose('/logout/')
    def logout_view(self):
        session.pop('logged', None)
        return redirect(url_for('.index'))


# views клиентской части  #############################################################
@app.route('/')
def index():
    return render_template('index.html')

########################################################################################  

# Create admin
admin = admin.Admin(app, 'Админка', index_view=MyAdminIndexView(), base_template='my_master.html')

# Add view
admin.add_view(MyModelView(User, db.session))

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


Добавлю:
пока не изменишь значение app.config['SECRET_KEY'] = '12345678290244' войти на страницу авторизации не получается. постоянно выдает выше указанный Traceback

############################################
Вместо:
session.update({'logged':True})
session.modified = True
указывал:
session['logged'] = True

Результат тотже. :(

!!!!!!!!!!!!!!!!!!!!! РЕШЕНО !!!!!!!!!!!!!!!!!!!!!!

Нужно просто в файле ...\app\templates\admin\index.html сменить:

{% if current_user.is_authenticated() %}
на
{% if session.logged %}

Единственно что хотелось бы узнать у знающих людей насколько безопасен данный метод???
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Tark
@Tark
Pyramid'альный мир
Ну... Первое, что приходит в голову, это сохранение данных для входа в переменных.

def logged_in():
    # в сессии будет храниться информация о том, что пользователь вошёл
    return session.get('logged')

# от этого класса должны наследоваться все классы админки - кроме индекса
class MyView(BaseView):
    def is_accessible(self):
        return logged_in()

    def _handle_view(self, name, **kwargs):
        if not logged_in():
            # делать редирект в некоторых случаях не стоит
            return self.render('admin/login.html')

class AdminIndex(AdminIndexView):
    @expose('/', methods=['GET', 'POST'])
    def index(self):
        if request.method == 'POST':
            frm = request.form.get
            login = frm('login')
            password = frm('pass')            

            # проверяете введённые данные...
            if ...
                session.update({обновляете сессию})
                session.modified = True
                return self.render('admin/index.html')
            else:
                return self.render('admin/login.html',
                                   error=u'Ошиблись паролем?..')
        # уже вошёл, но перешёл на /admin/
        if logged_in():
            return self.render('admin/index.html')
        return self.render('admin/login.html')

    # остальные методы класса


А с чем возникли сложности?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы