Handling mobile client Facebook SSO in Express backend - express

I'm trying to figure out the proper way of handling Facebook SSO, with a mobile client and an ExpressJS server using PassportJS.
Right now, I have a mobile client that's able to authenticate itself against Facebook SSO.
What's the proper way of handling authentication against my own Express server?
I'll try to explain myself here: Once the client gets the auth token from FB's APIs, he'll probably call my Express server to register the user, e.g. /api/user/register?fb_auth_token=.....
Do I then have to implement my own OAuth token logic (using Passport), so I can supply the client with some token so he can prove who he is for subsequent calls to my APIs?
Essentially give him a unique token for his user account in my DB?
Or do I simply save FB's auth token in my DB, and use that token for authentication in subsequent calls?
I know this is a bit more high level of a question than usual for this site, I'm just trying to figure out the main flow of using such SSO methods.

Related

Using the JWT from Next-Auth to secure my server as well

I am setting up a next.js app and was planning on using next-auth's JWT strategy for auth. I understand how the workflow works to protect your next.js routes and api endpoints within your API folder, but I have a separate express.js server that handles an API to my database that this app will be using.
My question is, is there some way to send the JWT token to my express server along with any api calls, and hold the secret on that server as well to authenticate the session and give the user access to the api routes?
My thought was to do this either in a next-auth callback or just send the jwt token along when needed. I was just having trouble finding a way to view the full jwt server side. All of the server-side hooks next-auth provide parse out the data from the JWT.
Thanks for any insight.
Yes you can achieve this using the CredentialsProvider what you have to do is call your login endpoint to recive your JWT tokens once the user logged in and store them in next-auth session then you can access it using useSession() from anywhere to get the token you need and send it along with any REQUEST you want to send to your backend server.

React Native OAuth2 and REST API authentication flow

I'm having a bit trouble understanding this predicament a REST API supporting React Native (Mobile App) with OAuth2 authentication.
I've managed to setup the OAuth2 flow and can login via OAuth2 provider. This communication is still just between the Mobile App and the 3rd party OAuth2 provider. How can I use those tokens I've obtained (and actually trust the request) to create an account in my REST API so that the server can actually generate a JWT token that will be used for future requests?
Can't seem to find an answer to this question. Would love some help with this one
Ok, I've managed to figure this one out.
To achieve what I want the Client (in this case mobile app) does the authentication flow and will receive an access_token and a refresh_token along with an id_token. The last one (id_token) contains the info about the user which the app should send to my REST API. Once the server receives it it will make an HTTP request to Google (my OAuth2 Provider) to verify that this token is in fact a valid one and issued by them.
After that I just create an account and issue my own token in response to the Mobile's App request.
It's explained here in Google Docs
Most likely all the major identity providers would follow along this path. Or, at least I'm hoping they do.

Storing client secret on client side

I'm using an external service called auth0 in order to get an access token and let my users use my api. Auth0 is using Oauth2 protocol.
In short The user adds a username and a password, I'm doing a call to auth0 by using a client_id (apps have an id) and client_secret and I get an jwt access token in return. Then from there I carry this access token to have access to my own api since I can check its validity.
I have been looking around about how secure it is to store client_id and client_secret on the client side (e.g. web (javascript)/mobile (native or hybrid with ionic)) and everybody was saying that it's not secure since everybody can reverse engineer the code and get the client_id and client_secret. Ok...I can take it...what Can I do with them if I don't have credentials in order to get the access token?
Given that I don't want to store the client_id and the client_secret, one solutions I have thought is to make a direct call to my api (Java) with the credentials and then my api make a call to auth0 and return the corresponding access token. In this way the client_id and client_secret is stored in the backend and somebody cannot get them easily. Is that safe?
However I have some endpoints, e.g. creating use account, sending sms for phone validation etc, that cannot have credentials. How do I protect the api in such case? If I can't store my own access token on the client side how could I get an access token and access my own api without credentials?
Thanks
One possible solution that OAuth spec suggests is that you could have three different servers for your application.
client-side
backend server and an additional authentication server.
The preferred way of doing this would be that the client would send the user credentials to the authentication server. The authentication server would be a back-end server which contains the client secret
The authentication server will authenticate the credentials and return back the token.
The client will then use the token obtained from the authentication server to access the resource API server.
If you wanna know more check out this video
https://www.youtube.com/watch?v=rCkDE2me_qk
In my opinion you are almost certainly using the wrong OAuth flow. I use Auth0 with Ionic as both a web app and a native Cordova app. I don't have the client secret in my client code at all.
If you follow the Auth0 quickstarts (https://auth0.com/docs/quickstarts), you should be choosing (Native/Mobile App) if you are deploying to app stores, and (Single-Page App) if you are deploying the web version of Ionic. From there you can pick Cordova (for native) or Angular (for SPA). These should give you instructions that implement OAuth flows which DO NOT require your client secret. My guess would be you are referencing a "Regular Web App" quickstart, which runs server-side and CAN safely hold the client secret. That's not the world you're coding in if you are using Ionic Hybrid/Native.
I would consider wrapping the call to Auth0 into your own server side implementation as safe. Your API takes user credentials and then calls Auth0 and this way your client_id/secret are secure on your server and the client can be reverse-engineered all the way without compromising your security.
Regarding the other APIs which cannot have credentials you are pretty much out of luck. Their very use case is to be used by an unauthenticated third party, so at least the account creation API cannot really be protected. However you can still use some nicely designed constraints to limit the attack surface. E.g. you can require an email address/phone number to register and you will not allow the same address/phone number twice. If you set up your process that you first need to confirm your email address before you can validate your phone number this will make the life of an attacker a lot harder. He would need a real working email address, and some automation to receive your confirmation mails before he could get to call your SMS service. You could also rate-limit the service per IP-address so an attacker cannot cause your SMS cost to skyrocket by issuing a lot of calls for SMS validation in a short period of time.

SPA + API Server + 3rd Party OAuth Authentication

Say we have SPA, OAuth service(Google or FB or Linked in) and an App server(our API) which servers the SPA to client.
Our SPA authenticates from client side with OAuth against 3rd party, say google or linked or FB, the method to use is said to be " implicit flow". Which returns the access token by passing an extra step.
Now how do we use this access token to communicate with our API. They are decoupled.
At this point client app(SPA) has the token and the FB|GOOGLE|LINKEDIN user_id which we got from the 3rd party OAuth.
Now lets say we are making a GET request to our server and it has to be an authenticated request. How do we use this token that we got from the OAuth
1) Do we make an API call from SPA to our APP server(our api server) with that token we got from OAuth and we remake the another call to the OAuth service again from the APP Server this time with the same token and make sure it is a valid token and create a JWT from that token and use jwt for the following api calls.
2) Or we implement a standard server side OAuth implementation using FB|GOOGLE|LINKEDIN and after authentication we save that access token on server side for that user and serve the SPA to client and pass that access token we got from OAuth server to client. Now that token can be used for following calls to API calls.
3) Or we implement a standard server side OAuth implementation using FB|GOOGLE|LINKEDIN and after authentication we save that access token on server side for that user and serve the SPA but this time create a JWT and serve that to client and client can now use the JWT for following calls.
I do not know what the right way is. Or if it is even a good way to Authenticate using OAuth with SPAs since Implicit Grant apparently is not a good way to go.

Rest API to validate external OAuth 2.0 access token

Im building rest api (using PHP, Laravel) which is used by mobile applications. The api basically is just commenting system.
Im planning to allow users to log in (to use this api) using their Facebook/MS/Twitter etc accounths using OAuth 2.
Flow would be something like this:
Authenticate user in mobile client using (user) selected OAuth provider
Get access_token (also maybe username/email) from OAuth provider and save it to mobile client
User access my rest Api (leaves comment), I include OAuth auth token to request
In server side I validate this token
Does this make sense? Is there any better ways to build this kind of system where the actual authentication server is completely different than the resource server?