Authentication w/ Express/Nodejs from Appgyver Supersonic Mobile App - angularjs

my ignorance is shining brightly on this one. I have a Web App that uses the MEAN stack (Mongo, Express, Angularjs, Nodejs) and some of the functionality is lackluster on mobile devices. So I'm developing a mobile version of the app on the Appgyver Supersonic platform. The Appgyver framework is based on an Angularjs front-end.
So I was hoping to just use the same Express/Nodejs server that I have running for the Web App and make queries/requests from the mobile app. Authentication is my current challenge. I assumed that I could send the username and password via a POST request and sign in and create a new session. I can sign in but I can't get access to the session cookie connect.sid so my next request has no session data with it.
TLDR; I have an Angular app that is on a different server than my Express/Nodejs back-end. I wish to authenticate the Angular app but can't figure out how to access the connect.sid cookie.

Since this never got any traction and I found what I think is a 'workable' solution I figure I'll answer my own question. If you see that I'm doing something really stupid here, please let me know.
When I login my client to the server, I respond with a session token. I store that same token on the User profile in Mongoose. I store the token on the mobile device using localStorage.
Whenever I send a request to the server I send the token with it, and have the Server check to see if the token matches the User token - if it does, I grab the User Profile data and assign it to req.user; which then seems to make the back-end operate properly.
Any major security concerns?

Related

What is the best approach for using OpenID Connect in a mobile app to authenticate the user to a backend?

I'm working on a product with two apps: one a single-page web app, and the other a native mobile app. Both make use of the same backend API. Currently the user authenticates using username/password credentials to establish a session cookie. I'm planning on adding support for authentication using OpenID Connect.
For the web app, I'm looking at following the advice for "JavaScript Applications with a Backend" in "OAuth 2.0 for Browser-Based Apps". In that scenario, the authorization code gets sent to the backend, which obtains the ID token and begins a cookie-based session.
I'm trying to work out how this would work on Mobile. The "go to" implementation of OAuth/OIDC on mobile appears to be AppAuth. From what I can see, AppAuth uses a different approach where you end up doing the auth code exchange on the device to get the ID token.
Should I have the mobile app send the ID token on to the backend to prove the user identity (and then begin the session)? Is there any best practice around doing this? Presumably at least the backend would need to validate the JWT and verify the signature?
Alternatively, can AppAuth be used to do a similar flow as done on the web app as mentioned above?
The mobile case does indeed work differently, and is defined in RFC8252, which defines the AppAuth pattern. Both the web and mobile cases have this in common:
Open a system browser at the Authorization Server URL with a Code Flow request URL
Cookies are not used in mobile views, and mobile apps can store tokens securely, unlike browser based apps. The mobile app will send access tokens to APIs, and also make token refresh requests when needed.
Out of interest there are easy to run versions of each in my online code samples, if you want something to compare against. Both flows are tricky to implement though.

Is this user authentication process reasonable?

I've been developing RESTful API server communicating with cross-platform clients such as Android, iOS, Web browser, and so on.
When a user login successfully by username and password, this server issue an access token(JWT, 5 minutes) and a refresh token(GUID, 20 days).
When we develop Android client app communicating with server, we just can store this tokens in mobile device and I believe it will not be a problem in terms of security( using SharedPreferences).
But when it comes to Web browsers, (React App) I had to tackle where to store these tokens. Finally, I decided HttpOnly Cookie, because I can manage easily CSRF attacks rather than XSS.
Soon, I doubt this is a typical design. For example, web browser users cannot logout whenever they want. So I determinate change the wrapper server(Node.js) between the React app and the RESTful API server.
In my second design, the React App and the wrapper server authenticate session-cookie model, using passport.js for exmaple. And when the wrapper recognize the request is authenticated, then the wrapper issue a short term access token(1 minute JWT) and reorganize the request by inserting the access token just issued in the header sent to the RESTful API server.
Is this reasonable process? Thank you in advance.
You could simplify your solution by removing the JWT access token altogether. The refresh token could be used as a session id. Every time a client issues an API call to the server the session id is sent in an HTTP header, so you can check if the request is legitimate.
Your approach of using a JWT token with a short expiration time is ok, but it brings some complexity to your system. In my opinion this approach is best suited for systems where you have an authentication service and a resource owner service. So the client would request an access token to the authentication service and use that token to communicate with the resource owner service. Then the resource owner can check the validity of the access token by just checking whether the signature matches the authentication service's.
I hope this helps you, let me know if I'm missing something.

How to allow mobile apps to login with Facebook and Google to access web service on GAE?

This is in relation to my other question about the need to create a Facebook app.
I've been reading a lot about how to best approach login for mobile apps users (iOS and Android) that access my web service running on Google App Engine. I'm still not clear how to best do it as I would like to offer login with both Google and Facebook. The app and the web service does nothing with Facebook or Google other than I would like to piggyback on their login.
Having only login with Google for GAE is very easy and the same goes for using OpenIDConnect. Facebook unfortunately does not support this.
Reading an old question here on SO where someone wanted to do the same as I it looks like the app should do Facebook Login and then get a token that it passes to my backend which needs to be validated by contacting Facebook. Is this how to do it today?
I also found Google Identity Toolkit, which seem to be what I need. However, I do not have a website or just apps. I would need to have the apps do the Facebook login and somehow provide my web service with something so it can validate the login info.
Later on an app user should be able to log in using randomly Facebook, Google and my custom username/password. The app and the web service should know the user is logged in and authorize it to access the REST API.
How do I accomplish this? BTW, I'm using Go on GAE.
I would really appreciate if someone could explain if there are several options how to do this, pros and cons, and provide an overview of the best approach and what needs to be done.
Many thanks for any help with this!
UPDATE
OK, thanks a lot everyone for the help and pointers. I have successfully run the quickstart sample app for iOS for my GAE backend. Basically, created a Facebook app and permissions credentials on my web service on GAE so that the sample iOS app can log in.
A bit of a gap still before I have an authenticated user in the datastore and can authorize successive API calls.
Main open questions at this point:
how to get the gtoken in the iOS app after successful Facebook or Google login?
should I explicitly call an API on my web service to pass in the gtoken or is this somehow automatic with Gitkit API enabled?
Thanks for any help!
UPDATE
To answer #1 and #2 myself, there's a "successful sign-in url" that can be given in the app engine config so the app knows where to call with the gtoken. Then after that it's like explained in the answers.
Looks like you have an app and a backend on GAE.
If you are using google identity toolkit, it will allow you to signin with Facebook, Google, and email/password.
When user successfully signs in to your app using identity toolkit, your server should receive a gtoken. You have two options here:
Pass the gtoken to your app and save it there. When your app makes API calls to your backend, you app should attach the gtoken to every request. Your backend should verify the gtoken(https://developers.google.com/identity/toolkit/web/required-endpoints) for every API that needs authorization.
Verify the gtoken, generate a token that your backend can recognize/identify the user. Then pass the token to your app and everything else is the same as option 1.
If you do not want to use identity toolkit, you can implement facebook login on your app/backend and use facebook token to communicate between your app and backend.
Whatever your decision is, apps that use your API should pass you something that your backend can recognize/authorize the user.
The answer is about using Google Identity Toolkit (GIT). GIT itself is an identity provider, which would be integrated with your apps and backend. The flow works along these lines:
your app requests login via its GIT API
GIT will perform the federated login with Facebook or other 3rd party provider (transparent to your app) and returns a GIT token to the app (representing a unique user from your end-to-end system perspective, i.e. apps plus backend)
the app makes a request to the backend in which it passes the GIT token
the backend verifies the GIT token validity (using this go GIT client API, for example) and from it can extract the identity of the user and thus validate the request
You can find more detailed info about the backend token validation in the backent endpoint doc, look for these sections in particular:
Understanding the Identity Toolkit cookie/token
Getting information for users
Now the actual token validation on the backend may take a few seconds, so it might not be practical to do it for each and every REST request from the app. If so you'd need to somehow:
save the info that the user of that specific app instance is
authenticated in something like a "session" managed between your app and the backend
map a specific REST request received by the backend to a specific such authenticated "session"
But I'm not sure how exactly is this "session" functionality done in the apps+backend context, I didn't write any apps yet.

Oauth social login using MEAN.js Restful sessionless API backend

I'm developing a Restful API using MEAN.js, which will be consumed by an AngularJS Web site and Phonegap Mobile Apps.
I'd like the user to be able to create an account and/or login using Faceboo, Google and Twitter.
I'm trying to use the same sample code that comes with MEAN.js seed application, but with the Node side of it, on port 3000 serving only the API, and the web site running on another server (currently on port 9000).
I','ve already implemented Token authentication using a Passport custom Local strategy, which generates a token, and the Bearer Strategy to autheticate API calls.
But I'm having problems with social login, to link social accounts to existing users.
From the Angular Client I call an api endpoint that redirects the user to the oauth provider (e.g. Twitter). When the user comes back, my serve has no knowledge of the logged user, since I'm not using sessions anymore.
I've tried to return the provider token to the client, but have problems parsing the anguler url. Then I coded another page outside angular that receives the provider token and calls an api endpoint sending the oauth token and the token issued by my api. It worked for Google, but not for Twitter. It seems twitter needs a session.
Anyway, what is the best approach to achieve what I want? How can I make this work?
Since your using Angularjs, take a look at this Angularjs library https://github.com/sahat/satellizer. The library pretty much opens up an oauth popup and checks the popup url for tokens. You can easily replicate the approach or just use this library. It works with a few social media providers like Twitter and its easy to add more.
I was in need of the same thing and so I set out to create my own. It's still in development but should give you a good start. Feel free to create a pull request and help to make it better. Maybe we can eventually merge it into their codebase.
https://github.com/elliottross23/MeanJsSocialLoginTokenAuth

Forms authentication with hybrid mobile apps

We are the process of developing a android phone app using IONIC framework and Web Api as the backend.
My question is ,is it sufficient to use Forms Authentication along with SSL to keep the phone app secure.
Our background is in Asp.Net web development and we could not see any examples that uses Hybrid mobile app development along with forms authentication,that makes me wonder if we are in the wrong track.
We implemented CORS along with WithCredentials both on Angular and Web API side, and the authentication piece seems to work fine for all subsequent calls in debug mode.
Do we need to take additional steps for security ,since its a phone app ?
Edit: I was reading about bearer token authentication with Web Api, is this a recommended way to go with phone apps ?
Thanks !
Yes my recommendation is to go with bearer tokens not with forms authentication.
You need to use OAuth 2.0 Resource Owner Credentials Flow which means that end-user provides the username/password only once for a specific endpoint i.e(/token) and then if the username/password valid you obtain something called Bearer Access Token.
This token is valid for specified period and you can configure this in your Web API. Once you obtain the access token, you need to store it securely in your android/hybrid app, then you keep sending it with each request to your web api protected end points using the Authorization header (Bearer scheme). I've written very detailed post which covers your scenario 100%. Please check the post Token Based Authentication and another one for authentication with AngularJS authentication which should work with your case. Let me know if you need further help.

Resources