Using Node's Passport to authenticate an Android app - android

I have a fully functional web app, where authentication was created using Passport. The application uses client-side, cookie-based session token. Basically, when a new session happens, the client's data is stored as Base64 AND signed client-side, so that the user cannot change it.
The login/pass mechanism obviously works 100% fine. Facebook, however, doesn't. The main issue is that in a web environment, the user is expected to get redirected to the Facebook page and which is passed the redirect URL to which the token is passed etc.
In a App environment, this doesn't happen: my (basic) understanding is that the client handles the whole oauth mechanism, and it is meant to provide the server with the userID and auth token -- which must then be checked by the server using a Facebook API.
So... is there a known "path" to go from "Web based Facebook login using passport" to "App based Facebook login using passport"? Or shall I not bother with Passport at all for the app side of things?

Related

Facebook Login with existing authentication system: how to pass the api token to the client?

I'm working on an Android app where there is an existing authentication system, based on email/password.
Whenever the user successfully logs in with username and password, a JWT token is created and returned to the app for making the authenticated calls.
Now I want to support Facebook Login, however some steps of the OAuth communication are not super clear to me. I searched the documentation but it seems to be a bit vague.
This is the process as I envision it:
User clicks on Facebook button
The app asks to the server a state token 821379812739871293 and calls the FB url configured like so
https://www.facebook.com/v3.2/dialog/oauth?client_id=123&redirect_uri=https://<myappdomain.some>/fb-callback&state=821379812739871293
The app opens a webview where the user can accept to login and share the email address
Facebook redirects to redirect_uri with something like this https://<myappdomain.some>/fb-callback?code=h21i3i2h13&state=821379812739871293
Within the callback call, the server:
checks if state token exists otherwise it rejects the FB callback
it uses https://graph.facebook.com/v3.2/oauth/access_token to obtain the access_token
it uses the FB APIs to retrieve the email address (have to check how to do this, but should be enough to call /me)
if email exists (sometimes it does not) it tries to find an existing user in the DB or adds a new one
[ UNCLEAR PART ] The callback returns a redirect to some OS-registered URL like http://<myappdomain.some>/login-success?apiKey=<jwt-token>
[ UNCLEAR PART ] the app reads the API key from the URL and proceeds making the calls to the backend
Is this correct/common practice?
Thanks!
EDIT: to clarify, I've seen this answer, however it is bad practice to store the client secret on the app side.
Moreover, in future I might integrate Instagram and LinkedIn authentications which seem to not allow or discourage bypassing the server with implicit oauth.

Socialite redirect to Facebook app instead of browser

I'm using Socialite in Laravel to authenticate users through Facebook in my back-end. The back-end functions like an API and sends the token back to the front-end after authentication so users can access their data using this token.
On desktop this works fine, but when a user uses our mobile application (Android and iOS simple webview frame) they get redirected to a browser when they click the login button. This breaks the user experience, because they have to type in their Facebook credentials, even though they are already logged in on the Facebook app on their phone.
Is there a way to redirect the users to the Facebook app to log in, while still preserving the login flow through the back-end? The easiest option would be to do login in the front-end, but then we would have to send the token to the back-end and I can't imagine any way to do this securely, because people could send any random token to the back-end to authorize themselves.
Maybe, you can create another Facebook app available only for web

Facebook registration flow from Android

I'm developing a webapp+android app that has its own registration flow - simple authentication using email and password.
I easily integrated the facebook login from the website, following the second scheme in this page.
Now, I need to 1-click authenticate the Android application with facebook. The main point is that, after the Android app is authenticated, i need to send from my server some specific cookies that are needed for permissions checks when the user wants to do some operations.
The problem is that I cannot authenticate through the facebook token: from what i see, the token would work even if it was taken from another application, so I cant send private data trusting only the fb token (even if it was sent by SSL), since it could be another app pretending it's the user.
Is there any registration flow similar to the one above for authenticating android apps?
Or there is any advice to overcome this issue?
Ok, facebook has fixed this by deprecating the offline_token and providing a longer access token from the client. This Token can be validated server side against my app id and app secret with this new endpoint:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID&
client_secret=APP_SECRET&
grant_type=fb_exchange_token&
fb_exchange_token=EXISTING_ACCESS_TOKEN
so I can be sure about the user identity.

How can I authenticate to my applications webservice after using Facebook SSO on Android?

I am creating an Android app that uses Facebook SSO to login and I'm not sure how to authenticate with my own webservices after I login to FB. When a user first opens my app they login to Facebook, authorize my application some privileges, and continue into my app. This part works great, but now to use my app they need to create an account on my server and talk to my webservices.
Right now I have a call to an authenticate webservice on my server that adds their Facebook ID and other basic info into a database and at the same time does a Diffie–Hellman key exchange so any future calls to webservices can be encrypted by a shared key. But the problem is that very first initial call to create this account and create this shared key, how do I authenticate that? How do I know this person is really the one who just authenticated with Facebook and not just someone who found the URL for my webservice and is creating accounts and saving the keys?
Facebook SSO returns an access token. If you'd like, you can pass that along to your server and your server can make a call to the Facebook APIs to check that it's a valid access token for that user (eg by calling https://graph.facebook.com/me?access_token=ACCESS_TOKEN) -- if it is, you're good and have verified that the user is who they say they are (or is a hacker with enough access to have a valid auth token for your app for Facebook, at which point their identity has been compromised on Facebook's end).
I think you have to pass a password along with your basic info upon profile creation. All in all, the Facebook SSO only gives your client application the right to access the profile user, but it does not garantee your web services that the caller is the actual owner of this FB account. I am afraid that subsequent calls from the Android client to the web service needs to be authenticated via a normal user/name password ( different from the FB account ) if you want to be sure that the caller is the one who retrieved the key the first time ( no matter what Facebook profile he might be linked to ).

Android SSO (Single sign-on) for app

Is there any free single-signon mechanism for Android that gracefully works with non-webapps? Say, something along the lines of...
You launch my app and use it until it makes a request from the app server that requires authentication. It responds to that request with a random token that the server will associate with you for a short time.
The app presents you with a username field, a password field, and a submit button.
You enter your username and password. The app then forwards your username and hashed password, along with the token generated by the app server, to the login service.
The login service determines whether or not your username and password are valid. If they are, it digitally timestamps and signs the token, and returns the signed token to the app.
The app relays the signed token to the server.
The server checks the signature, satisfies itself that it's valid and signed by an authority it trusts, and proceeds as though the user had presented IT with a valid local username and password instead.
I suspect I'm just getting lost in nomenclature, but the impression I've gotten so far is that all the usual SSO providers -- Twitter, Facebook, etc -- only allow users to log in using a normal browser, and that you're either not allowed to do what I described, or they do something to make it effectively impossible with anything besides a normal browser (like dynamically creating the login form via Javascript in an effort to prevent developers from trying to use their own apps as a login facade).
Alternatively, does there exist any workflow like THIS...
You launch my app and use it until the web service requires you to log in. The app server generates a token and returns it to the app.
The app spawns a new browser via intent that sends you to the login provider's web site, passing the token via intent to the browser (and ultimately the provider) as a POSTed formvar.
You log in using the browser window, and the browser window closes -- returning you to my app.
The login provider signs the token, then sends it directly to my app server via HTTP POST so I can note its submission, verify the cert, and treat it as though it were instead a valid username and password submitted directly by the user to the app server himself.
Have you tried or think of using Firebase? https://firebase.google.com/docs/auth/?hl=es-419
It has some useful tools, you can sign-in with multiple social connectors and user/password as well, and they provide a library to integrate the whole UI and server flow, they even take advantage of google smart lock for you.
Take a look at https://github.com/firebase/FirebaseUI-Android I used it in a personal project and saved me a lot of time.
What you described in Alternatively section looks like Authorization Code using Proof Key for Code Exchange (PKCE) OAuth 2.0 grant
https://www.rfc-editor.org/rfc/rfc7636
The flow is the following:
Your app generates a random key (code_verifier) and it's transformed value (code_challenge) and navigates to authorization server with code_challenge as a parameter
Authorization server redirects back to your app with authorization code
Your app sends authorization_code and the code_verifier to the auth server to get the authorization token
Server uses authorization_code and the code_verifier (it already has code_challenge, so it can verify that code_verifier is correct) and then returns to your app with the token.
On the practical side of it you can use something like Auth0 to implement it in your app.
Use Android Account Manager for SSO.
Providing references below just for knowledge. You have to dig into account manager.
Android developer: https://developer.android.com/training/id-auth
Blog with example: https://www.zoftino.com/android-account-manager-&-create-custom-account-type

Categories

Resources