OAuth登录完成后重定向到之前的URL(flask-dance)

2023-12-20

我正在开发一个 Flask 应用程序,允许用户使用 OAuth(以 Github 作为提供者)和 Flask-dance 库登录。由于某种原因,成功登录后,我无法重定向到我将用户发送到登录页面的页面。

当用户尝试连接时,例如http://localhost:6675/examples/tutorial.first/ http://localhost:6675/examples/tutorial.first/,用户被重定向到登录页面,在 URL 中显示我们应该重定向到的页面(http://localhost:6675/login?next=%2Fexamples%2Ftutorial.first%2F http://localhost:6675/login?next=%2Fexamples%2Ftutorial.first%2F)

问题是,当我成功使用 Github 登录后,应用程序只是返回到主页。

我在检查 Flask-dance文档 https://flask-dance.readthedocs.io/en/latest/以及文档make_github_blueprint()函数提到参数redirect_to and redirect_url,但是当我尝试使用它们时,我什至无法完成登录步骤。此外,它似乎只适用于静态地址,而理想情况下我想跳回到登录之前的页面。我还检查了这个问题 https://stackoverflow.com/questions/49749572/google-oauth-with-flask-dance-always-redirect-to-choose-account-google-page,但问题似乎有所不同。

有没有关于如何在使用 Flask dance 登录后正确进行重定向的示例?

这里有一些可能相关的代码片段。 在里面init.py 文件:

bp_github = make_github_blueprint(
    client_id="...",
    client_secret="...",
)
login_manager = LoginManager()
login_manager.login_github_view = 'github.login'
login_manager.login_view = 'login'

在 app.py 文件中:

@app.route("/login", methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return flask.redirect(flask.url_for('/'))
    return flask.render_template('login.html')

@app.route("/logout")
@login_required
def logout():
    logout_user()
    flask.flash("You have logged out")
    return flask.redirect(flask.url_for("login"))

@oauth_authorized.connect_via(bp_github)
def logged_in(blueprint, token):
    """
    create/login local user on successful OAuth login with github
    :param blueprint:
    :param token:
    :return:
    """
    if not token:
        flask.flash("Failed to log in.", category="error")
        return False

    session = blueprint.session

    resp = session.get("/user")

    if not resp.ok:
        msg = "Failed to fetch user info."
        flask.flash(msg, category="error")
        return False

    user_id = str(info["id"])

    # Find this OAuth token in the database, or create it
    query = OAuth.query.filter_by(
        provider=blueprint.name,
        provider_user_id=user_id,
    )
    try:
        oauth = query.one()
    except NoResultFound:
        oauth = OAuth(
            provider=blueprint.name,
            provider_user_id=user_id,
            token=token,
        )

    if oauth.user:
        login_user(oauth.user)
        flask.flash("Successfully signed in.")

    else:
        # Create a new local user account for this user
        name = info['login']

        user = User(
            email=info["email"],
            name=name,
            provider=provider
        )
        # Associate the new local user account with the OAuth token
        oauth.user = user
        # Save and commit our database models
        db.session.add_all([user, oauth])
        db.session.commit()
        # Log in the new local user account
        login_user(user)
        flask.flash("Successfully signed in.")

    # Disable Flask-Dance's default behavior for saving the OAuth token
    return False

我的回答可能有点晚了,因为您提到您的公司决定只允许用户在您的域上注册。不过,我仍然为其他可能有此问题的用户发布此内容。

要解决此问题,您需要有一个基本的登录页面,该页面首先存储用户通过域登录或 OAuth 登录完成登录后应重定向到的 next_url。 Flask 添加了next当您在 URL 上使用 @login_required 时,URL 中的参数应仅允许登录用户使用。你需要添加session['next_url'] = request.args.get('next')在您的登录路线中捕获next参数并将其存储在会话中next_url。现在,在 OAuth 登录的情况下,一旦用户被重定向到默认值redirect_url登录成功后,您将看到next_url会话中的值,并将用户重定向到该 URL(如果存在),否则呈现默认页面(通常是主页)。

我假设有两件事,1. OAuth 登录成功后您的默认 URL 是/home。这是使用以下设置的redirect_url在你的情况下 make_provider_blueprint 函数是make_github_blueprint。其次,我假设您的登录页面是用户未登录时的登录页面,并且它显示启动 OAuth 登录过程的 GitHub 登录按钮。您可能需要根据您的案例稍微修改此流程才能捕获next_url因此。

我在下面分享了处理这种情况所需的最少代码。请注意,我弹出next_url重定向前会话中的值。这样,如果用户在登录后尝试访问主页,则不应始终将其重定向到会话中存在的 next_url。

bp_github = make_github_blueprint(
    client_id="...",
    client_secret="...",
    redirect_url="/home"
)

@app.route("/login", methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return flask.redirect(flask.url_for('/'))
    session['next_url'] = request.args.get('next')
    return flask.render_template('login.html')

@auth.route("/")
@auth.route("/home")
@login_required
def home():
    if session.get('next_url'):
        next_url = session.get('next_url')
        session.pop('next_url', None)
        return redirect(next_url)
    return render_template('home.html')

如果这有帮助或者您需要任何其他信息,请告诉我。我很乐意提供帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

OAuth登录完成后重定向到之前的URL(flask-dance) 的相关文章

  • 如何在刻度标签和轴之间添加空间

    我已成功增加刻度标签的字体 但现在它们距离轴太近了 我想在刻度标签和轴之间添加一点呼吸空间 如果您不想全局更改间距 通过编辑 rcParams 并且想要更简洁的方法 请尝试以下操作 ax tick params axis both whic
  • InterfaceError:连接已关闭(使用 django + celery + Scrapy)

    当我在 Celery 任务中使用 Scrapy 解析函数 有时可能需要 10 分钟 时 我得到了这个信息 我用 姜戈 1 6 5 django celery 3 1 16 芹菜 3 1 16 psycopg2 2 5 5 我也使用了psyc
  • 使用 openCV 对图像中的子图像进行通用检测

    免责声明 我是计算机视觉菜鸟 我看过很多关于如何在较大图像中查找特定子图像的堆栈溢出帖子 我的用例有点不同 因为我不希望它是具体的 而且我不确定如何做到这一点 如果可能的话 但我感觉应该如此 我有大量图像数据集 有时 其中一些图像是数据集的
  • 如何在 Sublime Text 2 的 OSX 终端中显示构建结果

    我刚刚从 TextMate 切换到 Sublime Text 2 我非常喜欢它 让我困扰的一件事是默认的构建结果显示在 ST2 的底部 我的程序产生一些很长的结果 显示它的理想方式 如在 TM2 中 是并排查看它们 如何在 Mac 操作系统
  • 如何在Windows上模拟socket.socketpair

    标准Python函数套接字 套接字对 https docs python org 3 library socket html socket socketpair不幸的是 它在 Windows 上不可用 从 Python 3 4 1 开始 我
  • 如何使用包含代码的“asyncio.sleep()”进行单元测试?

    我在编写 asyncio sleep 包含的单元测试时遇到问题 我要等待实际的睡眠时间吗 I used freezegun到嘲笑时间 当我尝试使用普通可调用对象运行测试时 这个库非常有用 但我找不到运行包含 asyncio sleep 的测
  • 打破嵌套循环[重复]

    这个问题在这里已经有答案了 有没有比抛出异常更简单的方法来打破嵌套循环 在Perl https en wikipedia org wiki Perl 您可以为每个循环指定标签 并且至少继续一个外循环 for x in range 10 fo
  • Spark的distinct()函数是否仅对每个分区中的不同元组进行洗牌

    据我了解 distinct 哈希分区 RDD 来识别唯一键 但它是否针对仅移动每个分区的不同元组进行了优化 想象一个具有以下分区的 RDD 1 2 2 1 4 2 2 1 3 3 5 4 5 5 5 在此 RDD 上的不同键上 所有重复键
  • 为 pandas 数据透视表中的每个值列定义 aggfunc

    试图生成具有多个 值 列的数据透视表 我知道我可以使用 aggfunc 按照我想要的方式聚合值 但是如果我不想对两列求和或求平均值 而是想要一列的总和 同时求另一列的平均值 该怎么办 那么使用 pandas 可以做到这一点吗 df pd D
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • python 集合可以包含的值的数量是否有限制?

    我正在尝试使用 python 设置作为 mysql 表中 ids 的过滤器 python集存储了所有要过滤的id 现在大约有30000个 这个数字会随着时间的推移慢慢增长 我担心python集的最大容量 它可以包含的元素数量有限制吗 您最大
  • 当玩家触摸屏幕一侧时,如何让 pygame 发出警告?

    我使用 pygame 创建了一个游戏 当玩家触摸屏幕一侧时 我想让 pygame 给出类似 你不能触摸屏幕两侧 的错误 我尝试在互联网上搜索 但没有找到任何好的结果 我想过在屏幕外添加一个方块 当玩家触摸该方块时 它会发出警告 但这花了很长
  • 循环中断打破tqdm

    下面的简单代码使用tqdm https github com tqdm tqdm在循环迭代时显示进度条 import tqdm for f in tqdm tqdm range 100000000 if f gt 100000000 4 b
  • Python - 按月对日期进行分组

    这是一个简单的问题 起初我认为很简单而忽略了它 一个小时过去了 我不太确定 所以 我有一个Python列表datetime对象 我想用图表来表示它们 x 值是年份和月份 y 值是此列表中本月发生的日期对象的数量 也许一个例子可以更好地证明这
  • Python - 在窗口最小化或隐藏时使用 pywinauto 控制窗口

    我正在尝试做的事情 我正在尝试使用 pywinauto 在 python 中创建一个脚本 以在后台自动安装 notepad 隐藏或最小化 notepad 只是一个示例 因为我将编辑它以与其他软件一起使用 Problem 问题是我想在安装程序
  • 通过数据框与函数进行交互

    如果我有这样的日期框架 氮 EG 00 04 NEG 04 08 NEG 08 12 NEG 12 16 NEG 16 20 NEG 20 24 datum von 2017 10 12 21 69 15 36 0 87 1 42 0 76
  • 使用基于正则表达式的部分匹配来选择 Pandas 数据帧的子数据帧

    我有一个 Pandas 数据框 它有两列 一列 进程参数 列 包含字符串 另一列 值 列 包含相应的浮点值 我需要过滤出部分匹配列 过程参数 中的一组键的子数据帧 并提取与这些键匹配的数据帧的两列 df pd DataFrame Proce
  • 您可以在 Python 类型注释中指定方差吗?

    你能发现下面代码中的错误吗 米皮不能 from typing import Dict Any def add items d Dict str Any gt None d foo 5 d Dict str str add items d f
  • Python:元类属性有时会覆盖类属性?

    下面代码的结果让我感到困惑 class MyClass type property def a self return 1 class MyObject object metaclass MyClass a 2 print MyObject
  • 改变字典的哈希函数

    按照此question https stackoverflow com questions 37100390 towards understanding dictionaries 我们知道两个不同的字典 dict 1 and dict 2例

随机推荐

  • 如何在远程 ssh 连接中本地绘制 R 绘图?

    我目前通过 ssh 连接到一台远程计算机 我在 VIM 中设置了 R 我两边都用ubuntu 当我尝试从 R 绘制某些内容时 它将出现在远程计算机而不是本地计算机上 有什么办法可以在本地制作 R 绘图吗 您可以将 SSH 与 X切换以将图形
  • DIV 左侧垂直滚动条

    是否可以用css将DIV的垂直滚动条放在div的左侧 jscript 怎么样 我有一个简单的用例 所以选择了一个简单的 css 解决方案 div style height 250px div style padding 3px Conten
  • 使用 vanilla JS 添加 CSS 规则的最短方法

    我正在开发一个库 试图将其保持在 1KB 以下 我已经非常接近我的极限了 我需要添加一个 CSS 规则来控制显示隐藏行为 hidden display none important HTML 页面没有任何样式标签 这将是我唯一需要的规则 我
  • 无法从 Windows 注册表运行 vbs 文件

    我有一个调用 vbscript 文件的注册表项 如下所示 右键单击 cur 文件选择 更改光标 选项时将触发该注册表项 C Program Files Cursor Manager CustomCursor vbs 1 2 下面是vbs文件
  • 如何减少 Eclipse Ganymede 的内存使用?

    我使用最新的 Eclipse Ganymede 版本 特别是针对 Java EE 和 Web 开发人员的发行版 我安装了一些额外的插件 例如 Subclipse Spring FindBugs 并删除了所有 Mylyn 插件 我在 Ecli
  • 使用继承与接口的装饰器设计模式

    我想使用继承来实现装饰器设计模式 Decorator extends Component 因为我需要访问组件类的受保护字段 方法 问题在于 Component 类代表一种算法 它在构造时执行一些预处理并保存大量数据 现在 每次装饰组件时 我
  • 如何设置与单击一次应用程序的文件关联?

    我有一个点击一次的应用程序 我有一个关联文件 用于存储应用程序的数据 当用户单击这些文件之一时 我希望它打开单击一次应用程序并加载文件 我可以在发布中设置文件关联 图标和名称设置正确 单击文件将打开应用程序 但应用程序似乎没有传递文件的路径
  • 如果从 C# 代码调用,则捕获 EXE 文件中的错误

    我正在从 C 代码运行 exe 文件 由于某些原因 该 exe 文件中出现错误 它一直等待并最终给出弹出错误 abc exe已停止工作 等 但它不退出 The below code is calling it successfully pu
  • NetworkX:在Python中连接两个独立图的节点

    这个问题是关于尝试建模相互依存的网络 https en wikipedia org wiki Interdependent networks与 NetworkX 一起 有专用的包 例如Pymnet http people maths ox
  • node.js - 向子进程发送快捷键

    我的程序生成 ssh 作为子进程 连接到服务器 然后能够写入流并读取其输出 这一切都很好 当我将 ls 写入进程流时 我会得到文件列表 但现在 我想发送此进程的快捷键 以便我可以中止 ssh 会话中正在运行的进程 我知道这也可以通过流来完成
  • 如何在OpenCV中将16位图像转换为32位图像?

    我是 OpenCV 新手 我的程序读取 16 位无符号整数的图像数据 我需要将图像数据乘以 16 位无符号整数的增益 因此 生成的数据应保存在 32 位图像文件中 我尝试了以下操作 但得到了 8 位全白图像 请帮忙 Mat inputDat
  • 无法读取.net core 2.1中的用户机密

    我在尝试读取用户机密时遇到问题 我在startup cs中的代码如下 public Startup IHostingEnvironment env var builder new ConfigurationBuilder SetBasePa
  • 当受管节点是 Windows 主机时如何查找“env”?

    我需要获取 Windows 路径变量 UserProfile 进入 Ansible 剧本 例如 env USERPROFILE 如果我的受管节点是 Linux 主机 我想像 vars wPath lookup env USERPROFILE
  • 函数语句与函数表达式奇怪的行为

    var a function b console log typeof b gives undefined console log typeof a gives function 为什么两个输出有差异 我理解函数表达式和函数语句之间的区别
  • 在 Spark on Yarn 中使用类型安全配置

    我有一个从配置文件读取数据的 Spark 作业 该文件是类型安全的配置文件 读取配置的代码如下所示 ConfigFactory load getConfig com mycompany 现在我不将 application conf 组装为我
  • 带有父子行的 Angular Material 垫表的替代颜色

    我有一个有角度的材料mat table我使用 CSS 样式来替代行颜色 这是 CSS 样式 mat row nth child even background color e4f0ec mat row nth child odd backg
  • 如何正确安装 django-nose?

    我在运行 django nose 时遇到问题 Per the 安装说明 https github com jbalogh django nose 我安装的方式是 Running pip install django nose Adding
  • Python:如何使用splinter/浏览器一次性填写表单?

    目前 我正在网站上填写表格 内容如下 browser fill form firstname Mabel browser fill form email email protected cdn cgi l email protection
  • 有没有办法从 Excel 特定单元格收集数据并发送给 SQL Server?

    我有一个 Excel 表格模板 希望用户每天填写 一张表告诉我哪些单元格正在读 写 意味着我想将哪些单元格发送到我的数据库 该形式不是管状的 即 有时数据被设置 A3 gt A4 或 A3 gt B3 我想知道是否有 Excel 插件或任何
  • OAuth登录完成后重定向到之前的URL(flask-dance)

    我正在开发一个 Flask 应用程序 允许用户使用 OAuth 以 Github 作为提供者 和 Flask dance 库登录 由于某种原因 成功登录后 我无法重定向到我将用户发送到登录页面的页面 当用户尝试连接时 例如http loca