New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How does twitter.authorized know it's me? #88
Comments
Because although you've logged out of your local website, you haven't logged out of Twitter.com. When you try to log in with Twitter using OAuth, the following things happen:
Even if you log out of your website, restart everything, and so on, that doesn't change anything from Twitter's point of view. When you get to step 2 of the OAuth dance, Twitter is smart enough to see that you are already logged in on Twitter, and you have already agreed to sharing your information with this particular website, so they don't bother to make you confirm a second time. Instead, they just send you right back to the original website, with the special token for that website to use. Does that make sense? If you want to truly start over the OAuth dance (usually for purposes of testing), you have to go to the provider website and revoke your permission for sharing information with the consumer website. In the case of Twitter, specifically, go to the Apps section of your Twitter settings and revoke the permission for your Twitter app. After you do that, if you try to use Flask-Dance to login with Twitter, Twitter will once again ask you for permission to share your information with the other website. |
Thank you for that in-depth explanation! So is it accurate to say that calling |
No, it doesn't. If you have code that looks like this: @app.route('/')
def index():
if not twitter.authorized:
return redirect(url_for('twitter.login'))
# view continues here The first time you hit this code,
That will cause this code to run a second time, and at that point, |
Ok, I'm still confused, because I was logging out, deleting my cookie for my website, then hitting the 'log in with twitter' button with a breakpoint set on that |
Hmm, that is mysterious! I forgot that Twitter is using OAuth 1 instead of OAuth 2, which makes the logic different -- I may have unintentionally lied to you earlier. I don't have time to look into this more right now, but I'll see if I can figure it out later! |
More experiments done:
In both cases, when I check the 'Application' tab of Chrome devtools, I don't see any cookies set for the domain http://127.0.0.1:5000/. Digging through the code, this function in
The Also this function in
I don't understand how a blueprint can have the user's token, I'm looking into that now. Here's the line that seems to set the blueprint's token, it's in
It seems like the |
Ok, I think I've figured it out. I think the problem is with
I think what is happening is that because my code isn't fully hooked up, the |
Ah hah! Cache invalidation is one of the famously hard problems of computer science, and it looks like that's the root of the problem here. Are you using Flask-Cache here, or does this bug show up with the Is there any chance you can write an automated test that identifies this bug? That will make it easier to fix it so that it stays fixed. |
I don't think the problem is that the cache isn't being invalidated when it should be; I think it's that both the cache and the db are allowing an entry to be created when the Honestly, what I would be inclined to do is to just raise an exception if either(? or both?) the
Or maybe if you don't want to have it raise an exception, have it raise a warning(?): "Warning: Creating an OAuth record without an associated user will make the token used by all users, even anonymous users." That's not the best way to say it, but it might be a helpful first draft. I'm also not sure if it's really a bug as much as a design decision (what should happen in this situation?), and a weird situation I got myself into (having half the functionality created without the other half). |
That doesn't allow for using Flask-Dance without a user account system. (See the first option in this comment.) Maybe this is a problem that needs to be solved with better documentation? |
Could you maybe force the developer to explicitly declare whether they want the OAuth to be linked with a user account system or not? And then have the exceptions depend on that? |
Can you suggest an API for doing so? Which is to say, imagine that this feature was already implemented, and write some code that uses this already-implemented feature. That will help me understand what you're suggesting. |
Yeah, so right now my
I'm suggesting just adding a required parameter, so it'd look like this:
|
Update: Ok, two things:
Here's what my code looks like right now:
So it might be sufficient to simply look for whether that |
I don't really understand how I can log out, delete my cookie, then click the "Sign in with Twitter" button and it somehow knows who I am and just logs me in directly.
twitter.authorized
is evaluating toTrue
, and I saw that the code I think that's being evaluating to True is:How can the session still have a
resource_owner_key
andresource_owner_secret
after I've logged out, deleted my session cookie in Chrome, and restarted the server?The text was updated successfully, but these errors were encountered: