Firebase Cloud Messaging for Web: Refreshing Tokens - web

I use FCM to generate push notification tokens in a naive html + javascript app, then I save those to a database and use them to send notifications from another app. My users does not visit the naive html + javascript app at all after they visit once during registration. I read many posts about expiring fcm tokens, but most of them were about Android and the documentation was also a bit vague. Do those tokens generated by web apps expires? If they do, do you recommend any way to refresh them periodically without making users to visit the website again?
I observed that when I made some changes in firebase-messaging-sw.js and redeployed the application, tokens that I expected to be valid becomes invalid. Other than this kind of an action, are there things that can make my stored tokens invalid?
Thanks for your ideas.

Related

How you organize the interaction between Angular app and Xero OAuth2.0?

I am building Angular app that should interact with Xero API. Xero doesn't provide any SDK for Typescript (https://developer.xero.com/documentation/libraries/overview), but Node JS SDK seems to be the most useful lib for my task. But I am in stuck in how to organize the workflow between my app and their https://github.com/XeroAPI/xero-node-oauth2-app . I mean - I'd like to have some advises from the person who has already made similar apps (Angular + Xero) on following questions:
1) in this guide https://developer.xero.com/documentation/oauth2/auth-flow they say that user should open the page with URL like https://login.xero.com/identity/connect/authorize?... - but is there any way to make user log in without UI? If not -
2) how this process can be made in my case? In my Angular app I can make a button 'Log in to Xero' that will open new window:
window.open(xeroUrl, 'xeroAuth', 'location=yes,height=770,width=620,scrollbars=yes,status=yes');
where User log in, provide access to his organisation. The session tokens are created on the backend. But what next? How can I pass those tokens to my Angular app from that new window and then use them to make calls to Xero API?
3) Is the way to open new window for loggin in to Xero suitable for this case or maybe there is a better way to log in to Xero and get session tokens?
Thanks in advance for help.
Unfortunately, SPAs are not compatible with the Xero API.
You'll need a web server to manage your local session (OAuth flow, storage of Xero API tokens), and for your interactions with the Xero API.
While SPAs are a tempting option (they are convenient from a deployment point of view), there are changes coming to how browsers handle cross-site cookies, which break how SPAs perform session management.
I'd suggest reading https://leastprivilege.com/2020/03/31/spas-are-dead/ for more information and a discussion of the implications. The authors of the article created OIDC Client JS which is a great library for doing PKCE-based SPA auth in the browser, though it's only useful for same-domain applications now thanks to the impending browser cookie changes.
Further to this, the Xero API does not support CORS, so even once you complete the OAuth flow, the browser would be prevented from performing API requests from your Angular SPA.
To answer the specific questions:
1) The user will need to log in to Xero and grant consent for your app the first time they use your application. If you're storing server-side refresh tokens after the initial consent, your user will only need to log in to your local session, either via Xero SSO or another mechanism (user/password).
2) To create the initial Authorisation Request, it's best to use the node.js starter app. It will manage the OAuth redirect flow for you (it uses the excellent openid-client open source package for this).

User Registration and Authentication/Authorization with MEAN Stack

I need to register users with my AngularJS app. I would like hashing with salt to take place when storing the password into MongoDB. Then I would like the same user to authenticate and authorize for some of the actions he/she could take.
I come from Java/JavaEE background and have never done any registration/authentication/authorization work for a JavaScript app using MEAN stack.
Is there any reference/sample MEAN app I could refer to for understanding registration/authentication/authorization?
Should I be using Cookies or tokens for authentication?
Is there any reference/sample MEAN app I could refer to for
understanding registration/authentication/authorization?
I preffer passport.js. Plugs to express, Supports both Tokens and Cookies, it is easy to work with Angular.js via ajax.
Should I be using Cookies or tokens for authentication?
Take your own decision, but read this and this and this
I come from Java/JavaEE background and
Not clear but if you are new to web development, may be you should read this excellent post

Preventing from using my REST APIs from outside my own client JS app

I built an AngularJS application calling some REST API's belonging to my own backend (using Play! 2.2).
I'm using Facebook OAuth client in order to authenticate my users.
As being a Javascript App, my Facebook App Token cannot be "hidden".
Thus, anybody who picked up the Facebook App Token, by just reading the Javascript code could grab a user access token in a "legally" way and therefore use my REST API's.
How could I prevent it?
What is the best practice?
One way would be, I think, to use the server side Facebook's OAuth mechanism, rather than the Facebook Javascript SDK.
In this case, the Facebook app secret would be stored on my server and unreachable from the outside.
But as being a Single Page Application on client-side, I really want to avoid page redirection and benefit of the "popup" feature that comes with Facebook Javascript SDK.
There are a couple of things you can do.
Using the server side ("code") OAuth flow for facebook auth is much more secure. You can still avoid redirects by opening your own popup to initiate the login sequence, similar to what the Facebook JS does (only it goes to your server first).
Enabling HTTPS on your application is usually a good practice...
And if you're worried about cross site forgeries you can implement something like an anti forgery state token. See http://blog.codinghorror.com/preventing-csrf-and-xsrf-attacks/ and also google's instructions here https://developers.google.com/accounts/docs/OAuth2Login#createxsrftoken .

Firebase Authentication in a Chrome Extension Background Page

How would I authenticate with Firebase in a chrome extension? I need to specify the allowed domain list in the Forge. Chrome domain for the extension is just a big hash-like string.
I did read this: authClient.login problems
But the hashed based domain of a chrome extension is not being accepted in the Firebase forge. Is there another way to go about it? Currently am just reading the cookie firebaseSessionKey to just assume that I am logged in. But surely that can't be as secure as letting Firebase validate this session key.
As Rob points out, authentication cannot work in an environment that does not enforce origin restrictions. The fundamental problem here is that any authentication provider (Facebook, Twitter, Persona, or your own service) cannot issue an identity to a browser - i.e. it is meaningless to use Facebook to login to your browser (or extension).
The F1 add-on for Firefox ran into a similar problem (http://f1.mozillamessaging.com/) - where you would authorize F1 to post on twitter/facebook on your behalf. The extension had a website to along with it, from where you would serve the login page and proceed as you would normally in a web page. You'll need some code to communicate between the web page and your extension, chrome provides the tools necessary.
I would recommend the same approach - create a web page on a real domain (Github pages is awesome for this) to go along with your extension. This means your extension can't work offline, but neither can your login or writing to Firebase!
This will work using Google Plus Login Flow which I believe is the only one that allows cross authentication so the scopes are Google Plus Login.
"www[dot]googleapis[dot]com/auth/plus.login"
So what is happening here is you will get the access_token from the extension which you will be sending to firebase with the request using authwihtoauthtoken specifying google as a provider along with the access_token acquired from chrome.identity.getAuthToken()!
https://www.firebase.com/docs/web/api/firebase/authwithoauthtoken.html
Now the fact is that this access token could be issued by any other app, so we need to make sure that it is valid and has been issued for our app, basically we need to know there isn't man in the middle trying to access our database.
This verification is being made by the firebase.
They will check if this token belongs to the same application as the token has been issued to.
So you will need to create another set of credentials under the same application in the google developers console as for your extension. We will be basically doing the same thing as if we were to do it for our webpage but we will be inserting this new set of credentials to firebase's google oAuth in their security section.
They will do this check for us there. They will verify with google if the token is issued to the same app.
That's it.
Background Information.
https://developers.google.com/identity/protocols/OAuth2UserAgent#validatetoken
Use case
Sending ID tokens with requests that need to be authenticated. For example, if you need to pass data to your server and you want to ensure that particular data came from a specific user.
When to verify the access
All tokens need to be verified on your server unless you know that they came directly from Google. Any token that you receive from your client apps must be verified.
Google has a tutorial how to do this for python found at:
"github[dot]com/googleplus/gplus-verifytoken-python"
So basically what is happening here is; instead you doing to verification from on your server, firebase does this verification for you when you enter the CLIENT_ID and APP_SECRET into the firebase and enable the Google Authentication.
The way to do this correctly is a combination or same style of verifying to whom the client_secret was issued. Chrome will give you a access_token and then this access_token will be checked on the firebase's backend.

The "right" way to do oAuth from a mobile client

I am building a cross platform mobile application (using the Xamarian tools, MonoTouch / MonoDroid). I am trying to work through the authentication workflow and am running into a stumbling block. I have searched all over for a clear answer and have yet to find it.
Here is an overview of my current setup.
I have a web site built in nodejs.
I use passport.js to do oAuth login on the web site. This works great, users can login to my site using Twitter or Facebook.
Now I want to extend this same login functionality to my mobile clients.
I see 2 options
Embed the app id and app secret's in the mobile clients and make direct oAuth calls to FB or Twitter from the mobile app
Proxy the oAuth calls through my existing nodejs web server (keeping the secret keys on the server)
Option 2 appears to be the preferred way (as it avoids having to "ship" the secret in the mobile apps).
I have the proxy approach mostly working.
I open a WebView in my mobile client and point it at http://mysever/auth/twitter
This runs through my existing passport.js code and redirects the mobile WebView over to the Twitter login page.
The user then enters their creds on the twitter webpage on the device.
Twitter then calls my oAuth callback URL (which is my nodejs web server).
My server and Twitter handle the back a fourth handshake of obtaining the user profile information (As I understand it, this is the key to this approach, my server and twitter handle the handshake, the mobile client doesn't have to do anything or pass any tokens during this process)
Here is my problem:
It is this last step that stumps me. Once the handshake is complete on my server I have the user information I need on the server and need to send it back to the mobile client application
I can't figure out any way in the WebView control to grab the response object and grab a cookie, or header value (for instance) (this seems true for Android and iOS). I don't think it is platform specific. I think I am trying to do something that a WebView widget in mobile platforms just don't suport. It makes me think I am missing something obvious.
The only thing I have figured out is to have my web server "redirect" the mobile client browser to a fake URL that has the user info in the querystring. Something like myapp://info?userid=1234
Then in the mobile app I can hijack the URL loading and grab this url and get the data I need. I can then stash this userinfo, close the WebView control and move on to a native screen in my mobile application and user the userinfo in any subsequent REST calls to my nodejs server as a means of identifying the user.
This is massively kludgy for multiple reasons. The biggest of which is that the url is sent over the wire unencrypted and has all the data in plain text.
There has to be a better way to get the data from the web server back to the mobile client?
Or am I doing it all wrong?
The most straightforward way to implement oauth for Xamarin, both for iOS and Android, is using Xamarin.Auth. The starter documentation for the client is here. I think it should maintain everything securely and you will not have to worry about having to use your node server as a proxy.
You will need to provide your Application ID as part of the calls, but I don't there are too many or any security issues to worry about there.
I know this is going against what you already have implemented, but maybe this could help simplify things a bit.
This is the same dilemma that I have been dealing with.
This is how I currently deal with it.
In my app the client can come directly or via another service such as facebook which is my main one and hence the one which I have concentrated on.
Facebook can either redirect via a POST (desk apps) or a GET (mobile).
I check the initial request so see if has a service identifier - here is the facebook GET for example.
app.get('/', function(req, res) {
var paraUrl = URL.parse(req.url,true).query;
//The fb_source is shown -
//i need to go striaght to the facebook authorization since
//its coming from
//from a mobile device.
if (paraUrl.fb_source){
res.redirect('/auth/facebook'); //this is the passport part
return;
}
res.sendfile('index.html');
}
The facebook POST is slightly different in that you get an access token encode in base64url. The GET gives you a code which you can exchange for an access token but I had problems with it and just opted for tying into the passport system.
If a client comes direct I check for the session or a encrypted cookie which ties into the local strategy. This then checks the db for an access token which can used to access the facebook api for example.
If a client is unrecognised they are given the option to authenticate via facebook, google etc.
The main thing is that only 2 pieces of information are stored with the client, the passport session id and my app user id
connect.sid - encypted cookie
userId - encypted cookie
I would be interested to find out how other people are dealing with issue

Resources