singingwolfboy / flask-dance

Doing the OAuth dance with style using Flask, requests, and oauthlib.
https://pypi.python.org/pypi/Flask-Dance/
MIT License
997 stars 156 forks source link

Set a different redirect_uri for oauth_errors? #431

Open geolectric opened 4 months ago

geolectric commented 4 months ago

First of all, thanks for developing this project, I just started using it and it's fantastic.

During testing, I noticed that if I deny granting Facebook permissions when first creating an account, then the user is redirected to the page I set, but it requires the user to be authenticated, so it then redirects the user to the Facebook permissions request page, resulting in an endless loop (if user cancels permissions page).

What I'd like to happen is if the authentication was successful, then redirect to my page that requires authentication, but if there's an error, then redirect to my home page.

Is there a way to handle something like this with Flask-Dance?

singingwolfboy commented 4 months ago

Glad it's helpful! Try hooking into the "oauth_error" signal and returning a Response object with a redirect to where you want the user to go. https://flask-dance.readthedocs.io/en/latest/signals.html Does that help?

geolectric commented 4 months ago

I tried this:

facebook_bp = make_facebook_blueprint(
    scope="public_profile,email,user_birthday",
    redirect_to="private_bp.private",
    login_url="/login",
    authorized_url="/login/authorized",
    rerequest_declined_permissions=True,
    storage=SQLAlchemyStorage(OAuth, db.session, user=current_user),
)

...

@oauth_error.connect_via(facebook_bp)
def facebook_error(sender, **kwargs):

    blueprint = kwargs.get("blueprint")
    message = kwargs.get("message")
    response = kwargs.get("response")

    if blueprint and message:
        msg = f"Authentication error from {blueprint.name}! Message: {message}"

        if response:
            msg += f", Response: {response}"

        flash(msg, "danger")
    else:
        flash("An unknown authentication error occurred. Please try again.", "danger")

    return redirect(url_for("home_bp.home"))

But when I click Cancel on the Facebook permissions request page, it just keeps redirecting me back to it. It's like the return redirect(url_for("home_bp.home")) isn't occurring.

Also, in make_facebook_blueprint if I change to redirect_to="home_bp.home", then it does redirect me to my home page when I click Cancel on the permissions page.

So, it's like the return redirect(url_for("home_bp.home")) in @oauth_error.connect_via(facebook_bp) isn't being honored.

singingwolfboy commented 4 months ago

My apologies, it looks like I never actually built that feature! Flask-Dance had a similar feature for the oauth_authorized signal, but not for the oauth_error signal. Oops!

Well, as of version 7.1.0 (published on PyPI today), this feature now exists. I even added it to the documentation! Could you please try upgrading to the latest version of Flask-Dance, and let me know if it works now?