Testing Django Facebook App - python

I'm making a Django app with Fandjango and I'm trying to unit test it with Django's test framework. The only thing is, in order to test effectively I need a "signed_request" parameter that Facebook sends with every request. Right now I'm logging the requests my server gets from Facebook and copying + pasting the signed_request token I get, but that only works for a few hours at a time.
Is there a simple way to handle this without doing a mock of the whole Facebook API?
Thanks!

You can use Test Users:
http://developers.facebook.com/docs/test_users/
I think the access token never expires, or at less until you delete the Test User.

Well, I understand it's also possible to authenticate fully server side, using just OAuth without Javascript SDK. In that case you should be able to aquire a valid token yourself. There are, I think some libraries that can be used for that like:
http://pypi.python.org/pypi/django-social-auth/
However please note, I've never done this myself so it's more of a suggestion, than a definite answer.
EDIT
It seems like social-auth has some testing functionality that is capable of automatically signing in to a facebook account. You could probably copy the code from there.

Related

Can I use sessions for a Flask-based REST API?

I was using Flask for a small personal project of mine, and using render template and simple HTML files for the front-end.
I recently decided to switch over to a react front-end with a REST API in Flask.
However, since a lot of my old flask code depended on using sessions within Flask, I was wondering if sessions can still be used with a REST API.
There are essentially two parts to the question:
Is it technically correct (i.e. would it even work)
Is it advisable (If no, why not)
Thanks
Yes you can use sessions for login for a front end API. For backend APIs I suppose you could as well but something like jwt or oauth2 is much more common for a few convenience reasons. Not sure the set cookie header works when called via the JS fetch api so you may need to create your own session cookie with JS and possibly in middleware. You also have the option of having the login page not part of the API which would solve this problem.
Other than that as long as the session cookie is being passed to the API every time it is called which should happen automatically you will be able to use sessions in your Flask code.

Python authlib flask - how to handle refresh token?

I only need oauth2 for login so far, but I feel that to be reasonably complete, my app should still handle refresh tokens.
I'm fairly new to oauth, so here is my understanding:
By keeping access token lifetime short, but refresh token lifetime long, you force the client to "check in" regularly to renew the access token, and thereby maintain more control.
But how to actually do that using authlib and the flask integration?
There seems to be no refresh_token() on the FlaskRemoteApp, and I have not been able to find any example code showing this.
This seems to work to get a new token
res = oauth.myOauth2.fetch_access_token(refresh_token=session['tok_res']['refresh_token'])
session['tok_res'].update(res)
But fails when subsequently using the new access_token for an api call.
Could be a server error I suppose, or maybe I need to wait for the old token to expire before using the new one? The expires_at time, keeps updating and that makes no sense to me in that case.
It would be great if somebody could explain how refresh_token is intended to be used with authlib and flask.
Well, unless #lepture drops by with the answer, I have at least an answer.
I was simply missing grant_type='refresh_token' from my call.
So this now works as expected for me.
if session['oatoken']['expires_at'] - 2 < now: # refresh 2 seconds early
oatoken = oauth.myOauth2.fetch_access_token(
refresh_token=session['oatoken']['refresh_token'],
grant_type='refresh_token')
session['oatoken'].update(oatoken)
I played around a little with setting the update_token function in the registry, but was not able to make it work. In any case I believe this is only triggered if an api call using the token receives an "expired token" reply. In my case I'm only using Oauth for login, so I can just watch the expires_at time, and only hit the auth server when necessary.

Authorisation token: OAuth on Django back end, with front end call to 3rd party API. Is this a bad idea?

I am learning Django and have an idea for an app that would access data on the Microsoft Graph API for users of their outlook service.
It seems the cleanest way of doing this is by using a package like django-all-auth to handle obtaining and storing the authorisation token in the backend. There’s also an example on the Graph API website using python-social-auth.
However, I’ve been informed here that I can use a library like jQuery to make the API call directly, meaning the JSON data returned from the 3rd party API could bypass my server and go directly to the user’s browser.
With a 3rd party API requiring authorisation I’d need to get the auth token from my django back end to the front end so that it could be used in the Ajax request.
I appreciate that it would be an option to use the implicit or PKCE flows in the browser.
However, as an alternative I’d had the idea that I could use the server side OAuth flow to store the access token and refresh token in the back end and then send the auth access token from django back end to the user’s browser to be securely stored and used from there.
The benefit of this, as I see it, is that if the user’s access token expired you could make a call to the back end to use the refresh token in order to provide a new auth token, thus requiring the user to log in fewer times.
I also don’t see how this can be any less safe than the implicit flow, although me not seeing it doesn’t mean it doesn’t exist!
I know I’d have to use SSL to avoid any malicious actor snooping on the token. I’d also need to account for CSRF and XSS vulnerabilities, but thankfully django comes with solutions to both.
Would this method be a bad idea and considered bad practice?
My rationale for considering this is that it would reduce greatly the overhead of my server if I could cut out the intermediate step of rendering the JSON response in the page template before it’s sent to the user’s browser.
I think what I’m describing is addressed here, albeit with different frameworks.
If anyone else reads this and thinks of a problem with what I’m proposing please let me know.

How can I call an endpoint in my appengine instance without doing oAuth? (Mirror API)

I am trying to create some Glassware with the Mirror API. I am new to using AppEngine and Jinja2. I have python experience but never with a web framework before. So basically I am very new at this.
I have modified the Python quickstart for the mirror API to include many of my endpoints and designs. Basically I want to be able to be able to POST data from a constrained device to Glass. I have an endpoint all setup which works to accept and parse out the data and send the timeline item.
My problem is that the device itself is acting all on it's own and cannot provide input, therefore when I call my app from it e.g. https://foo.appspot.com?operation=deviceData the app presents the auth page and then nothing happens. I can see in the logs that the auth page is being sent, but the device has no idea what to do with this.
Basically, I need a way where I can hardcode credentials and get around having to do oauth everytime. What is the recommended way to do this? Another app which doesn't require auth which passes the data along? This would be fine as I only need to set this up with one user right now, it is for an internal demo only.
Is it possible to set my credentials in a header and auth automatically without handling any return, more like how basic auth works?
There are also the "Simple API access" keys. Would these work in this situation, I tried creating browser and server keys and tried them on the device and in the browser by doinghttps://foo.appspot.com?operation=deviceData&key=KEY_HERE but in both cases I was still prompted to login. Is this what simple access keys are for? Do they not work with the mirror API?
Basically my question is, what's the easiest way to allow access to my apps endpoints without having to oAuth or having a hard coded user which auto-auths?
Here is the project that I started with: https://github.com/googleglass/mirror-quickstart-python

Facebook authentication - are there different approaches?

I'm in process of building an app for Facebook using Python and Django. I'm investigating different solutions for integration with Facebook authentication API.
So far I've found the two viable solutions:
django-social-auth
python-sdk
I've already tried the first one and it seems to work nicely. I've just read about the second one and it seems to use Facebook JavaScript SDK.
My question is: are those two libraries doing authentication differently? Do I understand correctly that the first one uses OAuth directly to communicate with Facebook and get an authentication token from there, whereas the second one just displays some JavaScript enriched intermediate sites that request the authentication token from the level of a web browser?
In general: are there different ways of going about facebook authentication (JavaScript SDK vs something else)? Why is JavaScript SDK a recommended approach? And is the "something else" approach incapable of producing cookies and therefore less efficient in any way...
When you use a backend implementation (python, PHP, Perl, etc), you generally have to use URL redirects (Graph API) to interact with Facebook and the user. Personally, I don't think this is a good user experience.
Using the javascript SDK, you can do everything inline. Which means the user never has to leave your page to grant permissions, post to wall, send requests, etc. You can still use the backend libs to do other things. And you would need to if you are doing any "offline" activity or subscribing to real time events.
In the end, you end up with the same authorization rights. Both are making similar calls to Facebook to get a valid, authorized session. So either one, or both works.

Categories