-
Notifications
You must be signed in to change notification settings - Fork 74
Automatic Facebook Authentication not working #25
Comments
Can you post the code for your test script? |
Hi guys ,
|
Any luck getting this working? I'm also having this error. |
I'm pulling my hair out over here... I can manually fire up a basic webserver in another py script and can see response passed back to the web server. Herp Derp... |
I got what I needed to work. Here's what I ended up with.
.... |
Thanks @nincehelser ! This great stuff dude! However, I need to use facebook_graph.put_photo() and this code errors because its just an app access token not a client token... (grant_type = 'client_credentials') What I'm trying to accomplish is posting a photo that is taken with a raspberry pi to facebook whenever a physical button is pressed. Turns out that trying to do that with a headless device poses a bigger problem than I thought! Your code does get me to the point where I can post a message and have a thumbnail and a link to to the image. I looked at using IFTTT for copying the image to dropbox then having IFTTT post to facebook... but waiting 15 min for them to post is to slow for this purpose. I suppose I could push the pic thats taken to dropbox public, bitly the link, then push that link to your code... kinda silly though as it will fill up the dropbox account with photos! hmm... Hopefully the maintainer @pcardune is still alive! |
I'm also working with a Pi. Let me know what you find out. I don't understand why this authorization stuff has to be so cryptic, especially if you're trying to post to your own account. |
I'm having the same problem here, but it seems to be related to using the custom redirect_uri http://local.fbconsole.com:8080 (as suggested in the README). What this hostname really is resolving to is 127.0.0.1, which makes the Facebook auth API redirect the handshake to port 8080 on your local host. The redirect_uri is entered in your Facebook app settings. However, for this redirect_uri to work something must be listening on port 8080 on your local host, to receive the information needed for creating the access token. When using authenticate(), fbconsole uses a built-in http server for this stage. But for automatically_authenticate(), we have a different scenario with two pitfalls:
Using automatically_authenticate() with http://local.fbconsole.com:8080 as request_uri:
So what this means is basically, to be able to use auto authentication you must use another OAuth service (redirect_uri) to handle the final handshake. Or we would need to rewrite automatically_authenticate() so it starts the built-in http server in a background thread. A third solution would be to rewrite the mechanizer part of this code to use the low-level API mechanize.open() instead of mechanize.Browser(). This way it is possible to subclass the request handlers, making it easier to hijack the login flow and just get the data needed before actually going to redirect_uri. This would make a built-in httpd redudant, but probably makes for more complex code (involving http handler classes). Any other ideas? I'll fork in the meantime. |
By running one app which uses the authenticate() method and then starting another app with a call to automatically_authenticate(), it is possible to get to the last stage in OAuth handshake (after redirect_uri). The first app starts the builtin-in httpd and a browser window, and keeps the httpd running until the window is closed. Ignore the window (keep it open) and start the second app, which will try to connect to the built-in httpd set up right before. The first app will log something like this:
However making some initial tests it seems that the OAuth protocol used in the auto auth method is currently broken. After a successful call to the redirect_uri (our local http server, the log line shown above), a final request is made for Facebook to complete the handshake - which seems to be impossible right now. I keep getting these errors (last step, auto auth):
The error message suggests the redirect_uri has been changed. Looking at the debug logs it is the same in all requests, as well as on the facebook app page. I'm comparing the contents of the code parameter sent in this request with the query data sent to our local httpd and it matches exactly. Should it be permutated or obfuscated in any form? |
Thanks for looking into this @kchr. I'm not sure about the error code. In general the automated login implementation, even when made to work, seems fragile at best. If you are interested in using it and can get a pull request out that makes it work up to the point where you get that platform error, I can try digging into why that error occurs from the facebook side. |
Is it possible to get access to Facebook without any GUI and no manually input? I want to add pictures by cron job from a Raspberry Pi. |
@LA9SHA, yes, but only if you already have an access token. It's not possible to get an access token without a GUI. So you would have to get an access token beforehand and bake it in to your app. In this scenario, it would be a good idea to get a long lived access token that lasts for 60 days. Once you have that, you can refresh the access token periodically to make sure it continues to work. |
OK, seems like this is long-standing issue and I'm not sure if mechanize is actually a way we want to support this... I have no idea how it works for now & would recommend using existing tokens, which you can obtain for example with Graph Explorer: https://developers.facebook.com/tools/explorer/?method=GET&path=me On a related note, we may want to provide similar functionality with device login in the near future: |
I'm sorry if this seems like a rant; it's just some quick thoughts on the matter... Personally, I think making it possible to generate new tokens using only the API code (forcing the user to give away its user login credentials) would allow an application for silent access to a larger scope than the end-users intention, or even send the credentials to some other server before/after going to Facebook. It would also enable malicious applications to change the end-users password, effectively locking the user out. I think doing it through a browser session is a good way for the end-user to have control over what permissions it hands over to any app using the API, making malicious/bad code less potent and keeps the user login credentials away from the application/API implementations. The impact of potentially malicious code is heavily reduced. @LA9SHA :
As @pcardune already said: It's a one-time operation to get an access token. Depending on your use case you might want to register your own app key and get a credential token for that app (which does not expire until you specifically say so), instead of a simple user access token (which expire after some time). You will have to register for a developer account and get an app key, then use that app key/token in your application. It's a few steps extra compared to generating a user token using someone elses app key, but in return it only has to be done once. This way is probably, in 9 out of 10 cases, what you are looking for if you are writing CLI apps/scripts which doesn't require user input or a GUI. Registering as a developer and getting an app token is done here: The browser verification step part where you allow the application to access your profile is inevitable because of the security reasons mentioned in the beginning of this reply, but it really only has to be done once. |
I couldn't get this working on my machine, thus I will be unable to test it after refactor. Current solution would be to use long lived access tokens obtained through Graph Explorer or otherwise manually. Discuss in #25
Hello All, So i have fbconsole with automatically_authenticate working... almost... and need your help. bottom line... i can use fbconsole with the credentials for my fb account to post to /me/feed and /me/photos. yay! the problem is that I can't do it for anyone else. Here is what I have done. B. Here is a simple python script that i have been using to test authentication. import urllib fbconsole.OAUTH_SCOPE = ['publish_stream', 'read_stream'] profile_pic = fbconsole.graph_url('/zuck/picture') when executed with my credentials (the owner of the app) it works perfectly. I have another more complex script that allows me to upload pix/caption to the photos gallery without issue. However, If i try anyone else's credentials the post fails. Anyone have any ideas why? do i need to go through the process of a review to get this to work for everyone? I noticed that my App has the following approved items email, public_profile, user_friends. The permissions for posting seem to be missing. When I start the review process FB asks how to test the app and what the login procedure is. Not sure how to explain that we are using fbconsole or how to make the app available for them to test. I have added testers and developers to the app and tried using their email and pw but that also fails. Any thoughts on how to allow fbconsole to post for any user providing valid credentials would greatly be appreciated. --luis |
Hey! So long story short - automatic auth is a tricky thing, that doesn't work for me at all. It's not a part of API or anything we provide to developers officially... The app review is a separate process, and has nothing to do with fbconsole nor graph explorer - it's a new system that was introduced to make sure real world (working for real users) applications are requesting only permissions, that are actually used & required for their app. As soon as your app is ready to be used by users - submit review & provide guidelines how everything is done and what is the flow of your app login with fb. |
I find it curious that it doesn't work for you. I was having the issue listed above with the As stated there was no listener on localhost:8080 which was causing the process to give the error. What I found was that as long as you put the url to a valid website as the call back the problem goes away. For automatic_auth any valid url will work. The response from FB sends a redirect which mechanize must process. However... the response it not generated by the call back so the authentication code is processed correctly. Please try it again using any valid web address and see if that works for you. --luis |
no luck. Using debug = True I was able to repro the requests with browser and successfully authenticated in fb & then app, but within fbconsole - it's awlays the same thing. Looks like redirect must happen after POSTing a form, but instead server returns 200. |
So why would it work for me and not you? could it be the version of mechanize? mechanize: "0.2.5" --luis |
more on this issue... Although I continue to be able to use fbconsole to post to /me/feeds and /me/photos it only works for me. I created a test facebook user, made him a developer, and then in apps for my account invited the test user to be a developer of the application. The notice was sent to the test user, the test user accepted. However, when posting as that user authentication fails with the errors reported here. So... currently stumped. --luis |
Can be a setting on user profile, test facebook users are different a bit, the main problem is that login never was built to be automated this way, so having e.g 2-factor auth can kill it... Mac OS 10.10 / 10.9, python 2.7.6, Mechanize 0.2.5. OK, so for the short term - I'm going to continue without auto authentication support, if anyone will have a patch that works for them - that's fine we can merge. If not - long term access tokens can be used instead ( https://developers.facebook.com/docs/facebook-login/access-tokens#extending ) For long term - when Device Login will be launched for Public ( https://developers.facebook.com/docs/facebook-login/using-login-with-devices ) - we will use it instead. |
The Device Login procedure looks interesting. However, there are two concerns. B. Although not explicitly stated the access_token returned by FB is probably either a standard short term (1hr) or long term (60day max) token which could expire if the user does not use the device to post to FB within the expiration period. The nice thing about automatic_authentication is that once the user provides you with their FB authentication email/pw access to the users account for posting never expires. So the script could sit idle for 6 months and then post without issue unless the user changes his password. What we need is a replacement for the post_offline token which was deprecated many years ago. One thought that I have been meaning to investigate is using twitter to post to FB. Twitter has static tokens that never expire. Twitter also has an agreement with FB for cross posting. What I don't know is if the tokens provided to twitter by FB expire. I know that twitter and FB have a special relationship so my hope is that tokens provided by FB to twitter are of a different nature than the ones we have access to. The only way I know to test this is to setup a dummy FB and Twitter account, link them together, and then wait > 60 days before posting. Any thoughts on this would greatly be appreciated. --luis |
I want to automatically authenticate into facebook without using a browser or any users involvement.
I've tried several pieces of sample code that says it will do that, but I always come back to this error. I think it might have something to do with a certificate?
Any insight would be appreciated.
Thanks!
Traceback (most recent call last):
File "test.py", line 16, in
'http://local.fbconsole.com:8080/',
File "/usr/local/lib/python2.7/dist-packages/fbconsole-0.3-py2.7.egg/fbconsole.py", line 427, in automatically_authenticate
code = oauth["code"][0]
KeyError: 'code'
The text was updated successfully, but these errors were encountered: