How to setup an HTTP listener on localhost in a OSX App - swift

I am trying to build an OSX application using swift and storyboard. I am implementing Google OAuth for the app. Following the google guide https://developers.google.com/identity/protocols/oauth2/native-app#sample-authorization-urls, I am opening a browser with the a loopback authorisation url (i.e. after signing in, it loopbacks to localhost where the url contains authorisation code and other meta data.
To give a better overview of how the authentication workflow works:
User selects authorise button in app
Browser opens up with an url like:
https://accounts.google.com/o/oauth2/v2/auth?
scope=email%20profile&
response_type=code&
state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2.example.com%2Ftoken&
redirect_uri=http%3A//127.0.0.1%3A9004&
client_id=client_id
The google account chooser and permissions consent screen renders and prompts user to give permission..
Once user gives permission, the page redirects to localhost with the authorisation code or the error (when not permitted). The redirect url looks like:
http://127.0.0.1:9004/?code=auth_code&
scope=email%20profile%20openid%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email&
authuser=0&
prompt=consent
So now I want the parameter code in my app. Google document says I have to create an HTTP listener in order to get the parameters. So I want to setup an HTTP listener at that port (9004) and get the params. What HTTP library can I use to solve this problem?
I haven't tried to involve myself with any oauth library for osx and I want to implement myself but if there is a library which solves this problem with limited boilerplate suggest them.
Thanks.

I would recommend the AppAuth framework for macOS and iOS. It takes care of all of this for you, and includes an option to set up an HTTP server on the loopback interface.

Related

Instagram API Redirect URI SSL for localhost without the Warning

Instagram API requires redirect uris to have an SSL certificate (HTTPS connection).
I use Instagram API for my mobile app, and OAuth response should first invoke procedure in the app.
I am able to create a server to catch this call locally (on 127.0.0.1), but for the certificate, I can only create a self-signed one. The problem is that the browsers don't trust it and initially warn the user about the potential hazards, which is unacceptable for the user experience.
I saw a few similar questions on Stackoverflow, but unfortunately, I couldn't understand if they solve my issue.
How to avoid this warning?
Basically, even if they warns about https you can use api's. I had the same issue but I just tried to run the application on https port instead of http on localhost and it worked. So, Answer is you just need to run your application on https.
I have a solution for my specific case; I use Flutter for the mobile application. But overall you can find something similar for other cases as well.
Initially, I was launching the Instagram authorization window with url_launcher package. Basically, for iOS it launches the url in-app, but in a Safari Web View. In this way I am unable to control the flow in this web view. So, what I wanted to do is to catch a request to 127.0.0.1 when authorization is completed by running a local server in the app. It does work but throws a warning about security hazard due to a self-signed certificate, since Instagram requires https being used and 127.0.0.1 cannot have a trusted certificate.
Instead, now I launch the Instagram authorization window in-app with custom WebView using webview_flutter. It provides more flexibility, but most importantly I can track navigation. So now, Instagram redirects my user to the non-existing page on my website, which has a trusted certificate (but it doesn't really matter), but the aforementioned WebView can detect this redirect, parse the URL to retrieve the wanted code and prevent actual redirection by closing this web view. So, eventually, I get the wanted code in the app, so I can send it to my backend with extra user id reference.
So, basically, the workflow looks like this:
User clicks a button in the app to connect Instagram account;
The app launches a custom web view and opens Instagram authorization page;
After authorization, Instagram redirects the user to a dummy URL with the wanted code as a query parameter;
The custom web view detects this redirection;
Retrieves the code from the URL;
Closes web view (returns to the main app screen).

Working with Facebook login from localhost

I have a React/Horizon app with facebook login.
I am wondering if there is any option to work with facebook login from localhost?
There are some other good answers here. However I want to add information about how to create a Test app (as recommended by Facebook).
Go to the page to manage Facebook apps (you, the admin must be logged in): https://developers.facebook.com/apps/
Hover over the block containing your live Facebook app and click on the three dots button that appears on the bottom right corner. Then select Create Test App from the menu.
The test app will be created with a snapshot of your production app's settings. After this, you can independently edit the settings of your test app without affecting your production app.
See the documentation here: https://developers.facebook.com/docs/apps/test-apps/
Regarding the rest of the setup:
keep your app in Development mode
go to Settings -> Basic (left hand menu) and
enter "localhost" for the App Domain
change your Site URL to the localhost version (e.g. http://localhost:3000/users/auth/facebook)
Here are some (Jan 2022) screenshots of my test app settings, which I just use for Facebook login.
Settings -> Basic
Settings -> Advanced
Facebook Login -> Settings
You need to register as facebook developer and create you app there. Once you have your web app registered you can go to your app and click on add product.
Add Facebook Login. Then enable Web OAuth Login and add your localhost in the textfield below and save, you should be able to access it. Attaching a sample screenshot of my facebook app.
Disclaimer: This answer was written in 2019 and I have not been able to keep up with the latest changes introduced by Facebook, this is here for reference purposes.
So in my case doing the following things worked for me.
Make sure your application is in development mode
Make sure you don't have anything in Valid OAuth Redirect URIs when working from localhost
Make sure you don't have anything in App Domains also
Make sure you have entered localhost in your site url
I would like to add an update: July 2019
Facebook now allow localhost automatically in development mode and it is blocked in production mode. All you have to do is turn on development mode in your app settings and you are good to go.
You do not need to add localhost as a redirect URL anymore.
Here you can see the error at the Redirect URLs when I'm trying to add localhost.
You can use a tunneling tool like https://ngrok.com/ which is free for at least one instance. Then you can create a test App as already suggested and use the ngrok generated urls in this test app.
After test I see that we don't need to setup anything in facebook app
(even Site URL don't need to be localhost)
Just need to use https://localhost instead of http://localhost. Then login work and we able to receive response.
Note: If you see SSL warning after you enter https://localhost to browser. Just click on Advance -> Process to ... (unsafe)
The method FB.login can no longer be called from http pages.localhost, I get: App domains must match the domain of the Facebook Web Games URL (https), Mobile Site URL, Unity Binary URL, Site URL or Secure Page Tab URL. Please correct at least one of these domains: localhost
Using something like local-ssl-proxy is an easy way to solve this.
So I also have problem with working with Facebook Login from localhost in React and Express and I got this info:
"The method FB.login can no longer be called from http pages". After click login button, app just crashed.
My solution to fix this mess, was delete Facebook cookie from this localhost page. After this, I still have this error about http, but I can proceed and test login options.
Other solution is working in incognito mode.
I'm using Firebase to log into Facebook and honestly, the easiest thing was to just get your localhost served over HTTPS. I used ssl-serve for it, since I was working on a very basic ESM app with no build tools. But most build pipelines (e.g. Vue's vue-cli, React, etc.) have a CLI option for SSL as well.
What I used:
cd src && npx ssl-serve --ssl --clipless --port 5000 --silent
Then you just accept the self-signed cert ("Advanced" > "Continue" in Chrome/Brave) and you won't need to mess around with swapping the redirect URIs or domains under your Facebook app's config, nor the Facebook App IDs on Firebase.
Facebook provide Test App for your current app to get access to localhost environment. Create a test app on facebook https://developers.facebook.com/docs/development/build-and-test/test-apps/
and use the API and Secret to get testing on localhost.
I would like to share my experience for anyone who use firebase authentication combine with facebook login. Below solution work for me:
First, set your App Mode is development at https://developers.facebook.com.
Next, when you enable facebook login in Firebase Authentication, firebase will give you a link call OAuth redirect URI, you will have to add this link to the Valid OAuth Redirect URIs field in the setting page of your facebook app (inside tab Facebook Login). This is the most important step.
Finally, you don't need to do anything else. Good luck.
If you're using react and your local server is on http and still getting the error run this in the terminal to start up an https localhost
Windows:
set HTTPS=true&&npm start
Windows Powershel:
($env:HTTPS = "true") -and (npm start)
Linux and macOS (Bash):
HTTPS=true npm start
when it opens in the browser
click Advanced and proceed

hello.js facebook login redirect uri not supported, app ID invalid

I'm building a mobile app using Intel-xdk along with hello.js (a client side javascript sdk) for facebook login because it's the only thing that makes fb login work for me on Intel.
The hello.js instructions were hard for me to figure out even though they seem simple.
This is the init code as provided by the hello.js documentation. https://adodson.com/hello.js/
hello.init({
facebook: ************,
windows: WINDOWS_CLIENT_ID,
google: GOOGLE_CLIENT_ID
}, {redirect_uri: 'index.html'});
I need to note that I'm testing this on the intel-xdk emulator, on my iphone, and on the chrome browser. I am getting two different errors depending on where I test. I get either "app ID invalid", or "redirect uri not supported". Is there a different way I should be writing the redirect uri.
***UPDATE****
I got rid of the "windows" and "google" properties because I'm not using either of them for login. I also swapped "google" into the redirect uri. It didn't work when I used www.google.com, but DID work when I used https://www.google.com. So I think using "https" matters. This is what this init code block looks like now:
hello.init({
facebook: '178363645852696'
}, {redirect_uri: "https://www.google.com"});
Here are the different errors I'm getting now. On the intel-xdk emulator it goes right to google no problem. On the device it tells me I'm not logged in ( which isn't true). On chrome the message in the pop up window says this :
Given URL is not whitelisted in Client OAuth Settings: This redirect
failed because the redirect URI is not whitelisted in the app’s Client
OAuth Settings. Make sure Client and Web OAuth Login are on and add
all your app domains as Valid OAuth Redirect URIs.
I will continue to work on this and update my solutions, but additional solutions are wanted.
The sdk you are using is for websites not for cordova apps.
If you have code locally and building app using intel-xdk, then using a facebook cordova plugin is best solution, here is tutorial on how to get facebook API working in intel-xdk:
https://software.intel.com/en-us/xdk/article/facebook-connect-plugin-android-ios

Django piston, Django.auth, and asihttprequest

I have a website that uses Django piston for the API. I have also created an iPhone app that successfully connects to the API and parses the JSON and displays the correct content on the iPhone. The API resource URLs are as follows
http:/mysite.com/api/pics
http:/mysite.com/api/pics/username
I'm currently hard coding the username into the above URL from within the iPhone app and there is no authentication at all. I would like these URLs to require the user to be authenticated.
My website allows logging in via the /accounts/login provided by Django. However, the code redirects the users to their profile on the website, so I'm assuming I can't just use this URL in an asihttprequest from the iPhone.
So, if I want to log a user in, using the Django's built in authentication system, what URL should I be pointing them to. Also, once the user is authenticated I know that I'm supposed to use "is authenticated" and "challenge" for any "protected resource" in piston. I've seen code snippets that define these functions but I'm not sure where and how to implement them. I'm used to using a decorator that just says #login_required.
if you followed the instructions at: http://yml-blog.blogspot.com/2009/10/django-piston-authentication-against.html then looking at the example applications urls.py file https://bitbucket.org/yml/django-piston/src/dfb826a31ca8/examples/blogserver/api/urls.py you will see that authentication is passed to the resource handler.
If you've done this there is no need to use a decorator :)

Facebook Open Graph without a browser

For a middleware system with internet (which works inside a set-top box) I want to develop a primitive Facebook interface where users can type their user-names and password, showing their latest notification, messages and other casual stuff on the TV screen by using the recent Facebook Graph API.
This middleware program uses Java ME to run programs (such as this simple facebook app) and it can connect to internet however it doesn't have a real web browser. Without browser it can connect to any url to retrieve the JSON response however I am not sure how to achieve authentication without a real browser.
Under this circumstances, is it possible Facebook authentication? If you think so, what approach would you suggest ?
Thanks
Facebook provides trusted partners with a private Authorization API to get an OAuth 2 token from a username / password.
A more complicated approach would be doing something similar to how Netflix enrolls a device:
device calls server to obtain a Code
device shows code on screen and directs user to go to URL on server and enter Code
server redirects user to Facebook and obtains OAuth token, user told to go back to device
device calls server with Code and obtains OAuth token
device can now make calls directly on behalf of user
According to this documentation on "Desktop Application Authentication" I don't believe your desired result is possible:
Facebook's OAuth implementation does not include explicit desktop application support. However, if your desktop application can embed a Web browser, you can add Facebook support to your application easily using the same OAuth User-Agent Flow used by JavaScript clients.
However, it is clearly possible for certain vendors to do this, since Microsoft's Xbox 360 Facebook application does exactly what you are proposing. I'd be interested to see if anyone has dug up any API for doing this that Facebook doesn't want in their most obvious documentation.
This isn't an answer but I'm trying to do the same thing. Check out this guy's blog which uses another server to proxy the requests:
cory wiles blog
If you figure it out please post a detailed answer here so I can do it to.. :)
I think it is possible though it is pretty complicated and subject to sudden changes of Facebook interface. It might break the agreement between you and Facebook.
What you do is to emulate the Facebook.
One path you have to set up a Facebook application. Once you got the authorisation from user, you can to something with Graph API.
You need to the Facebook log-in process and authorisation process. There are some capturing tools on http/https request and response. Analyse them, both header and body.
Once you know the authorisation mechanism, you can replace it with you own. Everything afterward is on Graph API.
Another path is to emulate Facebook login and message and notification process. Capturing and analysis is needed.
In the past I have used a tool called screen-scraper (full disclosure: I used to work there) to automate logging in to facebook. Basically, it imitates a browser session; it allows you to set session variables (i.e. username, password) which would then be submitted to facebook, just as if the user had submitted them in a browser.
You may not be able to use screen-scraper in your set-top box environment (although it is java-based, so it's possible it would work). Even if it doesn't, you could implement a similar strategy in java, making the HTTP calls a browser would make to load the login page and submit the user's credentials. To keep the user's info safe make sure whatever HTTP client library you use supports HTTPS.
Proxy tools and extensions like Charles, Fiddler2, Firebug, Chrome's dev tools, etc. are helpful in seeing exactly what the browser is sending to the server in requests.