iOS/Django: How to perform dual authentication? - python

I had created an API that I use to get processed data from a postgresql db in the form of json. I am able to authenticate the user via the api using the Django Rest Framework and get an authentication token for the same. Now in some pages of my app, I need to display pages in a webview from the web app. These pages require a csrf token in order to be accessed. The csrf token is generated on the submit button of the login on the web app.
I can extract the csrf token from the cookies generated after login. So here's what I'm hoping to accomplish. Whenever I login from the login screen on my app, I want to programmatically create a webview in the background, fill in the login and password and tap the submit button in the web page. I will then proceed to extract the token from the cookies.
Most of the parts I have down, I am not able to figure out how to programmatically fill in the webview and hit the submit button. (The reason I want to hit the submit button is because the view checks if the request is a post and ajax). Can anyone shed some light on how I go about performing dual authentication in this manner?

If anyone is curious, I managed to perform dual authentication via a hidden webview at the login. I hit the api url to get the api auth token, and simultaneously hit the web app url on my webview. I fill in the username, password and tap the submit button through code
func webViewDidFinishLoad(_ webView: UIWebView) {
print("loadFinished")
let loadUsername = "var emailText = document.getElementById('email'); emailText.value = '\(username)';"
let loadPass = "var passText = document.getElementById('password'); passText.value = '\(pass)';"
let submitAction = "var passFields = document.getElementById('login_button'); passFields.click();"
webView.stringByEvaluatingJavaScript(from: loadUsername)
webView.stringByEvaluatingJavaScript(from: loadPass)
webView.stringByEvaluatingJavaScript(from: submitAction)
print("Executed!")
let req = URLRequest(url: URL(string: "https://app.xyz.io/abc/")!)
if tf != true {
webView.loadRequest(req)
tf = true
}
}
After my request loads and authenticates successfully, I merely retrieve the csrf token and sessionid from the session's cookies.
Hope this helped someone!

Related

React/Ionic Spotify Authorization redirection

I am coding up a Spotify app with a microservices architecture.
I have a few services, including a frontend (built in React/Ionic) and an auth service (Python FastAPI). These services are running in docker-compose.
I have the auth service handling all of the Spotify Authentication, and I just need a button on the front end to redirect to the Spotify login page.
above is the code that is executed when the button is clicked. I have a setupProxy.js file configured, so the url is fine.
The flow is this : button click > GET request to auth service > auth service returns a redirect response > once user is logged in, Spotify redirects back to auth service with code, should post access code to database. Then return to frontend page. The frontend will pull the access code from the database.
The problem is I am not getting redirected to the spotify page from the frontend. I know the redirect works, because I have another backend service, which I made a test call to the auth service from and it redirects me.
This is what is executed on the auth service call.
This is the test call from the backend to auth that definitely works.
I basically need an equivalent of the /test route above in React/Ionic.
Any help would be appreciated as I am completely stuck.
Update:
Spotify code is now coming through (i.e. button is clicked, browser redirects to my auth service, then redirects again to callback address with access code in URL, but even on a new browser I am not asked to sign into spotify it just comes straight back.

remember me option in GAE python

I am working on a project in which i am working on a signup/login module. I have implemented the sessions in webapp2 python successfully. Now i want to implement the remember me feature on login. I am unable to find anything which can help me. I do know that i have to set the age of session. But i do not know how. Here is my session code.
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
#webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
Config:
config = {}
config['webapp2_extras.sessions'] = {
'secret_key': 'my-super-secret-key',
}
Kindly help me.
First in case you don't know the difference between sessions and cookies
What is a Cookie? A cookie is a small piece of text stored on a
user's computer by their browser. Common uses for cookies are
authentication, storing of site preferences, shopping cart items, and
server session identification.
Each time the users' web browser interacts with a web server it will
pass the cookie information to the web server. Only the cookies stored
by the browser that relate to the domain in the requested URL will be
sent to the server. This means that cookies that relate to
www.example.com will not be sent to www.exampledomain.com.
In essence, a cookie is a great way of linking one page to the next
for a user's interaction with a web site or web application.
.
What is a Session? A session can be defined as a server-side storage of
information that is desired to persist throughout the user's
interaction with the web site or web application.
Instead of storing large and constantly changing information via
cookies in the user's browser, only a unique identifier is stored on
the client side (called a "session id"). This session id is passed to
the web server every time the browser makes an HTTP request (ie a page
link or AJAX request). The web application pairs this session id with
it's internal database and retrieves the stored variables for use by
the requested page.
If you want to implement something like "remember me" you should use cookies because data stored in session isn't persistent.
For setting and getting cookies in webapp2:
response.headers.add_header('Set-Cookie', 'remember_me=%s' % some_hash)
request.cookies.get('remember_me', '')
I strongly recommend you to read this article that has explained this stuff thoroughly.

Get access token for Soundcloud desktop application?

Toying around with Soundclouds SDK for Python with an impact of TKinter as GUI. Now I want to generate a access token for each user so that I could access more API-endpoints.
I have created an applicaton in Soundclouds Developer portal with a link to my callback.
There is nothing corresponding to generating a access token for an desktop application. Only for server-side application. I tried this code below:
import soundcloud
# create client object with app credentials
client = soundcloud.Client(client_id='YOUR_CLIENT_ID',
client_secret='YOUR_CLIENT_SECRET',
redirect_uri='REDIRECT_URL')
# redirect user to authorize URL
redirect client.authorize_url()
I have set my keys, and redirect_uri as the callback on my webserver. When I run my python file from the terminal, I get this:
File "token.py", line 9
redirect client.authorize_url()
^
SyntaxError: invalid syntax
Using Python 2.7.5+
What is causing this? I want to generete my access token and print in later on.
The solution might be that I need to create an instance of an web browser window, make the user accept the app using Soundcloud connect. The I grab the url and sort out the "code" in the url. Exchanges the code against an access-token and stores it inside a text-file. So that I could grab it later on.
A simple way of obtaining an access token is by first authenticating via the User Credentials flow, which exchanges your username and password for an access token:
client = soundcloud.Client(client_id = 'CLIENT_ID',
client_secret = 'CLIENT_SECRET',
username = 'USERNAME',
password = 'PASSWORD')
print client.access_token
try:
redirect(client.authorize_url())

Get facebook user/app token in a python desktop app

I am writing a python desktop app that will access a user's facebook photos. The app currently supports flickr, which uses a similar oauth authentication process, but I am struggling to figure out how to authenticate the app for facebook. For flickr, the basic steps are:
App opens a browser on the authentication page
user gives the app permission to access the account
App receives a token as a http response that can then be used with flickr's api
I am hoping that there is something similar for facebook, but I haven't been able to figure it out.
There are a variety of facebook API libraries for python, such as Pyfb, which provides a simple way of accessing graph data, but none of them provide an obvious way to do the authentication steps above and retrieve a token that can be used. Here's the example from Pyfb, which presumes that the user token will be manually entered by the user, which is totally ridiculous for a desktop app...
from pyfb import Pyfb
#Your APP ID. You Need to register the application on facebook
#http://developers.facebook.com/
FACEBOOK_APP_ID = 'YOUR_APP_ID'
pyfb = Pyfb(FACEBOOK_APP_ID)
#Opens a new browser tab instance and authenticates with the facebook API
#It redirects to an url like http://www.facebook.com/connect/login_success.html#access_token=[access_token]&expires_in=0
pyfb.authenticate()
#Copy the [access_token] and enter it below
token = raw_input("Enter the access_token\n")
#Sets the authentication token
pyfb.set_access_token(token)
#Gets info about myself
me = pyfb.get_myself()
Here's a shot at answering my own question.
First, the reason the code fragment above doesn't work. The call to pyfb.authenticate opens the authentication link in the default browser. After the user logs in and allows the app access, facebook is supposed to redirect the URL in the browser to something like
https://www.facebook.com/connect/login_success.html#access_token=ACCESS_TOKEN&
expires_in=SOMETIME
In the pyfb code sample, the user is supposed to copy the access token from the URL bar and all should be well. But... presumably because of some security concerns, facebook will perform some Javascript shenanigans which will instead leave you with:
https://www.facebook.com/connect/blank.html#_=_
(It turns out that you can work around this by digging through the browser history on some browsers -- see https://bugs.kde.org/show_bug.cgi?id=319252)
The solution to this for a desktop app is to open a web view within the app. The Javascript code apparently will correctly detect you are authenticating within an app and spit out the full URL with token. So here's an example using Python gtk and webkit:
import gtk
import webkit
view = webkit.WebView()
sw = gtk.ScrolledWindow()
sw.add(view)
win = gtk.Window(gtk.WINDOW_TOPLEVEL)
win.add(sw)
win.show_all()
win.connect("destroy", lambda *args:gtk.main_quit())
client_id = 'XXXXXXXXXXXXX' #your unique app id
auth_url = 'https://www.facebook.com/dialog/oauth?response_type=token&client_id=%s&redirect_uri=https://www.facebook.com/connect/login_success.html'%(client_id,)
view.open(auth_url)
def load_finished(view,frame):
#function will print the url with token second time
print frame.get_uri()
view.connect("document-load-finished",load_finished)
gtk.main()

Obtaining an Access_token to read Page Insights

I've been working on using python to get access to Facebook insights information. I was able to get public information (e.g. 'likes' from cocacola's page) in addition to app insights for apps that I have developed.
Because I am the admin and developer for both pages and apps, when I go to facebook.com/insights I will see a section for pages and a section for apps. I want to be able to get insights for both from the graph api and store them on my personal database. Getting the app insights were not difficult. I obtained my app_id and app_secret when I created my app and then followed the process under App Login at this page http://developers.facebook.com/docs/authentication/. This gave me an app access_token which I could use to get app insights.
When attempting to do the same for pages, I have had more trouble. As many previous posts have mentioned, most of the facebook documentation has to do with a facebook app getting an access_token to manage or read insights from a page. I understand that this is useful for apps that interact with a user's page. However, my instinct says that I should be able to get an access token with read_insights for a page that I am the administrator of without having to go through an external app.
The only way that I've been able to read the insights for my page has been using the Graph Api Explorer. I used the Explorer to obtain an access_token (through the access_token button, allowing the Explorer to access my personal data and requested manage_pages and read_insight extended permision). Then I followed the instructions under Page Login at the /docs/authentication/ page that I posted above, to get an access_token for the facebook page I administer. Then I could finally run https://graph.facebook.com/PAGE_ID/insights?access_token=RETRIEVED_TOKEN. However, this is an incredibly cumbersome way of finding the access_token. Is there a way to get this token that is less cumbersome? Thanks for your help. I've been struggling with this for quite a while.
I've also included the code that I used to get the access token for my app.
def get_access_token():
args = dict(client_id=FACEBOOK_APP_ID, client_secret=FACEBOOK_APP_SECRET, grant_type="client_credentials" )
url = "https://graph.facebook.com/oauth/access_token?" + urllib.urlencode(args)
response = urlparse.parse_qs(urllib.urlopen(url).read())
access_token = response['access_token'][0]
return access_token
Why not using classic way:
Create an app and login to it using facebook (JS SDK for example), with the offline_access and read_insights permission.
The offline_access will give you a permanent access_token that you can use to access the insights anytime you want.
The JS SDK (method FB.login) will return an object, containing the access_token you need.

Categories