当前位置: 首页 > 知识库问答 >
问题:

烧瓶登录@登录所需的装饰器不重定向到登录页面后会话已过期

邹玄裳
2023-03-14

使现代化

下面的烧瓶重定向(响应代码302)似乎是作为对\u dash-update-component请求的响应传递的:

b'<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n<title>Redirecting...</title>\n<h1>Redirecting...</h1>\n<p>You should be redirected automatically to target URL: <a href="/login">/login</a>.  If not click the link.'

这解释了下面dash_renderer抛出的语法错误,所以这导致我在server.py中添加以下内容:

@server.after_request
def check_response(response):

    redirecting = 'Redirecting...' in response.get_data().decode('utf-8')
    dash_response = request.path=='/_dash-update-component'

    return make_response('', 204) if redirecting and dash_response else response

现在,我可以通过向Dash组件返回“204无内容”响应来模拟类似Dash的PreventUpdate,但是我没有收到重定向回登录页面的额外请求。注释掉请求后的函数,然后跟踪请求前的所看到的请求,实际上显示调用了login()路由,并返回render\u模板('login.html'),但它并没有在浏览器中呈现。。。。

下面的原始帖子

在过去的几天里,我花了大部分时间试图彻底检查我们的登录程序,以添加一些生活质量更新和修改。出于这个问题的目的,我感兴趣的是在主Dash应用程序中经过一段时间的不活动后注销我们的用户。

我的方法是为我们的登录页面注册路由,然后将/dashapp的Flask路由指向应用程序返回的响应。index()其中app指向仪表板应用程序。一旦他们登录到Dash应用程序,我就有一个before_requestdecorator,它将更新session modified属性和session expiration(出于测试目的,需要5秒)。我还将@login\u requireddecorator应用于这个调用的函数,以便login\u管理器。如果用户在触发\u请求之前的decorator时不再经过身份验证,则会调用未经授权的\u处理程序。我认为我的逻辑在这里是合理的,但我仍然有一些问题,我将在下面描述。

我能够登录我的用户并将他们重定向到/dashapp的主Dash应用程序,并且我可以毫无问题地使用该应用程序。现在,当我等待5秒钟以允许会话过期时,单击我的Dash应用程序中触发dash回调的组件会在控制台中产生以下错误:

破折号渲染器。v1_7_0m1602118443。min.js:20语法错误:意外标记

我知道有些函数需要一个JSON响应,显然收到了一个HTML响应,但我无法确定这是什么。它还阻止我重定向回登录页面,当用户不再经过身份验证并触发before\u请求decorator时,我希望调用该页面。

我的代码结构如下(不是说config.py只是我的SQL连接):

应用派克

from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html

from server import app, server as application, User, login_manager
from flask_login import logout_user, current_user, login_user, login_required
from flask import session, redirect, render_template, url_for, request
from views import main

app.layout = html.Div([

    dcc.Location(id='url', refresh=False),

    html.Div(id='page-content')

])

@application.route('/login')
def login():

    return render_template('login.html')

@application.route('/login', methods=['POST'])
def login_post():
    
    if current_user.is_authenticated:

        return redirect('/dashapp')

    user = User.query.filter_by(username=request.form['username']).first()

    #Check if user exists
    if user:

        #Check if password is correct
        if user.password==request.form['password']:

            login_user(user, remember=False)
            return redirect('/dashapp')

@login_manager.unauthorized_handler
def unauthorized():
    
    if request.path!='/login':
        return redirect('/login')

@application.route('/logout')
@login_required
def logout():

    logout_user()
    return redirect('/login')

@application.route('/dashapp')
@login_required
def main_page():

    return app.index()

@app.callback(
    Output('page-content', 'children'),
    [Input('url', 'pathname')])
def display_page(pathname):

    if current_user.is_authenticated:
        content = main.get_layout()
    else:
        content = dcc.Location(pathname='/login', id='redirect-id')

    return content

if __name__ == '__main__':
    app.run_server()

查看/登录。html

<html>
  <head>
    <title>Flask Intro - login page</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
  </head>
  <body>
    <div class="container">
      <h1>Please login</h1>
      <br>
      <form action="" method="post">
        <input type="text" placeholder="Username" name="username" value="{{
          request.form.username }}">
         <input type="password" placeholder="Password" name="password" value="{{
          request.form.password }}">
        <input class="btn btn-default" type="submit" value="Login">
      </form>
      {% if error %}
        <p class="error"><strong>Error:</strong> {{ error }}
      {% endif %}
    </div>
  </body>
</html>

server.py

import dash, os, datetime
from flask_login import LoginManager, UserMixin, current_user, login_required
from config import connection_string
import dash_bootstrap_components as dbc
from credentials import db, User as base
from flask import session, g, redirect, url_for, request, flash, render_template
import flask

external_stylesheets = [dbc.themes.BOOTSTRAP]

app_flask = flask.Flask(__name__)

app = dash.Dash(
    __name__,
    server=app_flask,
    external_stylesheets=external_stylesheets,
    update_title=None,
    url_base_pathname='/'
)

app.title = 'Login Testing Interface'
server = app_flask
app.config.suppress_callback_exceptions = True

server.config.update(
    SECRET_KEY=os.urandom(12),
    SQLALCHEMY_DATABASE_URI=connection_string,
    SQLALCHEMY_TRACK_MODIFICATIONS=False
)

db.init_app(server)

#Setup the LoginManager for the server
login_manager = LoginManager()
login_manager.init_app(server)
login_manager.login_view = 'login'

#Create User class with UserMixin
class User(UserMixin, base):

    def get_id(self):

        return self.user_id

#Reload the user object
@login_manager.user_loader
def load_user(user_id):

    return User.query.get(user_id)

@server.before_request
@login_required
def check_authentication():

    session.permanent = True
    server.permanent_session_lifetime = datetime.timedelta(seconds=5)
    session.modified = True
    g.user = current_user

main.py

from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc

from flask_login import current_user

from server import app, server

def get_layout():

    return html.Div([

        dcc.Location(id='url-main', refresh=False),

        dbc.Button('Click me', id='test-click', n_clicks_timestamp=0),

        html.Div(id='testing')

    ])

@app.callback(
    Output('testing', 'children'),
    [Input('test-click', 'n_clicks_timestamp')])
def update_test_div(clicks):

    return f'Last clicked: {clicks}'

credentials.py

from flask_sqlalchemy import SQLAlchemy
from config import engine

db = SQLAlchemy()

db.Model.metadata.reflect(engine)

class User(db.Model):

    __table__ = db.Model.metadata.tables['my_sql_table_with_user_details']

在此提前感谢您的指导!


共有1个答案

令狐钧
2023-03-14

我建议写你的登录和登录后的路线作为一个单一的功能

@app.route('/login', methods=['POST','GET'])
def login():
    if current_user.is_authenticated :
        return redirect('/')
    if request.method == 'POST':
        user_name = request.form.get('username')
        password_entered =request.form.get('password')
        
        present_user=User.query.filter_by(username=user_name).first()
        if present_user.password == password_entered:
            login_user(present_user)
            next_page= request.args.get('next')
            print(next_page)
            return redirect(next_page)  if next_page else redirect('/')
        else:
            flash('Incorrect  Password',category='danger')
            return render_template('user_login.html')
    else:
        return render_template('user_login.html')

如果您从login_required函数重定向到Login页面,您可能会注意到顶部的链接 /url说

/login?下一个函数

当我们写作时

下一页=请求。阿格斯。获取('下一个')

我们在之后得到剩余的URL?然后将用户重定向到它的来源

 类似资料:
  • 记录器文件中的日志- org.springframework.Security.Access.event.loggerlistener-安全授权失败,原因是:org.springframework.Security.Access.accessdeniedexception:访问被拒绝;通过身份验证的主体:org.springframework.security.authentication.ano

  • 我现在一直在努力使用我的登录页面来让组件呈现Loggedin组件。我的前端是Reactjs,后端是NodeJS。我对nodejs、expression和react都是新手。 在loginform组件上,我使用fetch进行了一次post,它将用户名和密码传递给后端的相应endpoint。没问题。在后端,它读取我存储用户(不使用任何数据库)的jsonfile来查找匹配项,如果用户名和密码都匹配,则它

  • 这是views.py的内容: 在转到“/”时,我被重定向到“/accounts/login”,它将我带到登录页面。我输入用户名和密码后,在“验证”打印语句printd“登录”到终端。 到目前为止还不错。现在,我不再被重定向到“/”,而是再次被重定向到“/accounts/login”,并再次显示输入用户名和密码的页面。为什么?

  • 我使用的是Spring Security 4.1.1,但我遇到了一个问题:我试图访问URL,应用程序会重定向到登录页面。到现在为止,一直都还不错。 但是,成功登录后,应用程序会再次将我重定向到登录页面,并且不会创建任何会话,因此即使尝试直接访问URL(在URL栏中键入),应用程序也会重定向到登录页面。 有一些URL我必须要求登录才能访问它们。其他的,我可以访问无需身份验证。这些我不需要验证的URL

  • 我使用的是和和。一切都很好,但是当会话超时的时候,我会得到以下错误”,因为我已经在布局的main.gsp文件中调用了session变量。现在,我希望在每次会话超时后重定向到登录页面,并且不显示错误页面。要在会话超时后重定向,我已经在文件中这样做了 但是有这么多页,所以很难写每一页。还有其他的方法做这件事吗?请帮忙。

  • 问题内容: 我正在做一个简单的论坛,由一系列论坛组成,每个论坛分别代表首页,主题,postitit,登录名和用户列表页面。在某些页面上,当用户未登录时会出现一个链接。 我想要实现的是在登录后触发重定向(在RequestDispatcher上使用forward()),以便浏览器返回到用户在单击登录链接之前所在的页面。为此,我看到了两种解决方案。 第一种解决方案是使用带有登录按钮的HTML 和一个不可

  • 每个人登录后,我一直无法使用Laravel重定向。连接工作,在我登录后,它重定向到一个空白页面,但如果我更改url路径,我可以访问不同的网页。我们将不胜感激!我正在使用LDAP进行连接,它正在工作。 请让我知道,如果有任何其他代码,我应该提供。 非常感谢。 (重定向IfAuthenticated.php) 命名空间应用程序\ Http\中间件; 使用闭包;使用Illumb\Support\Faca

  • 问题内容: 我想设置我的网站,以便如果用户点击该页面并且他们已经登录,它将把他们重定向到主页。如果未登录,它将正常显示。由于登录代码内置在Django中,我该怎么做? 问题答案: 我假设你当前正在使用内置的登录视图, 或你网址中的类似内容。 你可以编写包含默认视图的登录视图。它将检查用户是否已经登录,如果已经登录则重定向,否则使用默认视图。 就像是: 当然可以相应地更改你的网址: