I am developing application using Angular2 and ionic in back end i am using node. In my application i have some html forms these forms contain common input fields and image upload.
If the user don't have net connection user can able to complete the form without any problem. Once he get internet connection at that time it will upload to server.
How can we implement this feature in web and mobile separately ?
Whats the best solution for this scenario. Please suggest i don't have any clear picture about this one.
To understand what offline scenarios are good candidates for a mobile web app, it helps to first understand the key technologies that make it possible.
Mobile web apps can be built with three core capabilities, and all of these are part of the new HTML5 standards:
Browser application caching of pages
Local storage
Local database
Browser application caching allows a manifest to be created listing pages that should be cached and made available offline. Normally, when you visit a URL, a server request is made to return the page. Setting up an application cache manifest tells the browser how it can use pages already downloaded rather than just immediately displaying an error when there is no longer a network connection.
Local Storage is a standard that retains local web app data (even when the browser is shut down) using a key/value system that works similarly to browser cookies. However, it is different from browser cookies in two important ways. First, cookies are resent to the server with every HTTP request, and it would waste a lot of bandwidth to resend all offline data when the server doesn’t need it. Secondly, cookies tend to max out at around 4k of data, while local storage usually gives an application as much as 5 MB of data to work with per domain. 5 MB may not sound like much, but when used carefully, it can go a very long way in terms of offline local storage.
Local Database removes the 5MB limit of local storage and allows data to be indexed so that multiple properties can be queried quickly. This is only an HTML5 proposed standard at present; only Internet Explorer and Firefox have implemented it so far. Safari and Chrome use an older, deprecated system called Web SQL. This means if you need this level of functionality, there is a significant amount of extra work and complexity to support both standards across all major browsers. Hopefully, that won’t always be the case and major browsers will conform to the finalized HTML5 specifications.
When user is offline store form data in localStorage, and when it comes online get data form localStorage upload it to server and remove data from localStorage.
localStorage.setItem('form_data', formData) //Store data in localStorage
localStorage.getItem('form_data') //Get form localStorage
localStorage.removeItem('form_data') //Remove from localStrage
Add eventlistner on window
if (typeof navigator.onLine !== 'undefined') {
window.addEventListener('offline', function (ev) {
userOffline();
});
window.addEventListener('online', function (ev) {
userOnline();
});
}
function userOnline() {} // when user online
function userOffline() {} // when user offline
Related
The gist of it all is that I'm trying to fetch audio metadata from a user's google drive files to store them into firebase.
At first I intended to do this locally, entirely client-sided, because my front-facing web/iOS/Android app is in flutter;
but as it turns out, there's almost no library handling audio metadata properly, and after dabbling with it, I realized I could probably get some formats (say, .wav & most RIFF-type audio files) to work, but doing an entire library to handle all kinds of audio metadata was a task significantly bigger than my original plans. Another option would be to create interfaces between C++ code and/or JS code into my Flutter application, but I'd have almost no control over that, it's not the easiest of process, and there would be possible inconsistencies between platforms.
I might make that library eventually, but in order to facilitate my work, I decided to use a server as a middleman that'd run with node and handle the file requests and metadata treatment, & also facilitate the interactions with firebase for me by making them handled by a service account.
Now, this makes me run into one issue : how to handle the google Auth.
When my user logs into my app, I get all the required auth scopes (google drive files access and write, contacts, email, etc) for my app; it goes through the consent screen and I get authenticated.
I'm still a little confused with the recommendations from google and best practices in this case, since my app, in itself, did not require an auth system outside of getting access to the google drive files through google identification, and I therefore do not have Firebase/Firestore users; I can simply store them in my (firestore) database for identification purposes (or maybe tie in the frontend flow to my firestore app to also create a user when logging in through google if that is possible. I'm currently using the google sign in
flutter package.)
To come back to my actual problem now that the situation is laid out :
Should I just transfer the auth tokens (and maybe reverify them in some ways to avoid impersonation) from my frontend app to the server through a HTTPS post request or through headers, and use them to directly query the Google Drive API (I wouldn't even need to store them outside of memory, which would be relatively safe against any attacks on the server itself), handle the files and the possibly expired token ?
Should I modify my frontend workflow so it directly grants access to my server who would handle the session rather than getting the tokens locally ?
In the first case, I would most likely simply use the users UID as identifiers for the firestore data (none of it is sensitive anyway, it would simply be playlists and some metadata). In the second case, I could probably implement a stronger security on firestore using the firestore rules,but it'd require a significant amount of refactoring and logic changes in my frontend.
In case that wasn't clear, I wish my server to make all the Drive related requests (after getting the proper authorizations from the user of course) and handle these without having to request the files locally in frontend. Both solutions (and others if available) should work, but I'm wondering what the best practice would be in the context of the Oauth2 system used by google and the fact that the authorization is transitioning between client and server and could be subject to security issues.
I'll add code/visual representations if this isn't clear enough. It is to me, but I obviously designed the mess.
In Google Chrome manifest v2, the background script had persistent store which allowed the Auth0.js to store the auth token in memory. To augment this, the developer could store the authentication token in local storage. Storing the auth token alone is not a good solution because this would require the app to fetch the token from storage every time it needs to run an authenticated query. Which is where having the auth token in memory comes in handy.
Unfortunately, this goes away with manifest v3 as service workers are not guaranteed to be persistent. I've seen solutions out there suggesting that you could use the options page to initiate Auth0 login but it is not clear to me if the options page is persistent either and whether or not it shares a persistent store with the other components of the extension (i.e. foreground, background, popup).
So my question boils down to this, what is the best practice for logging a user in (using Auth0) and keeping the user logged in between browser sessions?
First off, a bit of a frame challenge: why is having the token in storage while the background is unloaded a problem? If the requests are frequent enough for storage access to be a significant slowdown, on those timescales the background won't be unloaded (only if it's been idle for some period). Do you really have a case where you have requests that are infrequent BUT cannot tolerate storage access latency?
That said, there is a new tool for storing small amounts of data persistently throughout one browser session (= lifetime of memory of prevously-persistent background) but between Service Worker loads: chrome.storage.session storage area.
If you look at the rationale document for this API, it mentions specifically:
Use Cases
Computationally-intensive data
Data that is too computationally-intensive to compute every time the Service Worker starts up
Unencrypted sensitive data
Unencrypted sensitive data that needs to be accessed for the duration of the browser session.
Check on the sensitive data, maybe-check (my challenge applies) on the "avoid computing every time". Note that the API is still the same as the regular storage: so, still asynchronous - if that's a problem.
Given a third-party webpage www.somepage.com handing out specific URLs to subscribed websites in the format of www.somepage.com/site/3ir3jsd - how can I track that a user having an account on www.somepage.com has visited one of the subscribed websites without resorting to cookies / localStorage ?
A standard approach would be to store a cookie for www.somepage.com and add www.somepage.com/site/3ir3jsd via an IFrame. This has several issues as new laws and browser defaults prohibit third-party cookies and local storage to be loaded.
Is there some other mean to achieve this? I see that this is a potential privacy issue and would of course ask for permission to do this and would prefer secure / non-privacy-infringing methods. All major browsers have to be supported which rules out browser extensions too (looking at you Internet Explorer 9-11). Maybe JavaScript? But I don't want the user to have to "login" to my pages service on every subscribed webpage. Storing their session cookie in the first-parties localStorage / cookie is a potential security risk though (which would be needed when using JavaScript + storing their session data).
Another approach I have checked is client certificates but they are poorly supported (read: often unsupported) by mobile browsers and the use-ability of adding them is horribly in most of them too.
No matter how I reason about it, it seems as if there is no secure way of implementing a client side rendered single-page-application that uses/accesses information on sessions for authentication, either via cookies, without severe compromise in security. I was mainly looking to building a React app, but it seems as if I will need to build it with SSR for a relatively secure version of authentication.
The use case that I'm especially thinking of is where the user logs in or registers and then gets a cookie with the session id. From there, in a server side implementation, I can simply set up conditional rendering depending on whether the server stored session has an associated user id or not and then pull the user information from there and display it.
However, I can't think of a client-side rendered solution where the user can use the session id alone on the cookie that isn't easily spoofable. Some of the insecure implementations would include using browser storage (local/session). Thanks.
I think the major issue here is that you are mixing the two parts of a web page (at least according to what HTML set out achieve) and treating them both as sensitive information.
You have two major parts in a web page - the first being the display format and the second being the data. The presumption in client side rendering / single page applications is that the format itself is not sensitive, and only the data needs to be protected.
If that's the case you should treat your client-side redirect to login behavior as a quality of life feature. The data endpoints on your server would still be protected - meaning that in theory an unauthenticated user could muck about the static HTML he is being served and extract page layouts and templates - but those would be meaningless without the data to fill them - which is the protected part.
In practice - your end product would be a single page application that makes requests to various API endpoints to fetch data and fill in the requested page templates. You wouldn't even need to go as far as storing complex session states - a simple flag notifying the client if it is authenticated or not would suffice (that is beyond what you would normally use for server-side authentication such as cookies or tokens)
Now let's say I'm a malicious user who is up to no good - I could "spoof" - or really just open the browser dev tools and set the isAuthenticated flag to true letting me skip past the login screen - now what would I do? I could theoretically navigate to my-service/super-secret without being redirected locally back to the login page on the client side - and then as soon as the relevant page tries to load the data from the server with the nonexistent credentials it would fail - best case displaying an error message, worst case with some internal exception and a view showing a broken template.
So just to emphasize in short:
A. If what you want to protect is your TEMPLATE then there is no way to achieve this clientside.
B. If what you want to protect is your DATA then you should treat gating/preventing users from navigating to protected pages as a quality of life feature and not a security feature, since that will be implemented on the server when serving the data for that specific page.
I'm building a Sencha Touch 2 application that retrieves data from a webservice. It's been decided that it'd be a good idea to use an optional PIN setting on the app for extra security when you launch the app from idle. I'm not really sure what the best way to manage this is.
The web service isn't capable of storing the PIN itself, and the app is also designed to be used offline as well as online, so the number needs to be stored on the device itself in local storage. I'm not convinced this is providing any level of security, and I'm also concerned that on iOS local storage is apparently treated as temporary so setting the number in local storage doesn't necessarily mean it's always going to be there.
The webservice already returns an expiring auth token to the device on which is required for all requests to the API. To my mind that's secure enough, but the idea of the PIN seems to be important to the client.
How would you manage this requirement?
Unlike cookies which passed between server/client (and could be accessed by both of them), sessionStorage / localStorage are 100% stored in the client by a concrete browser, sessionStorage temporarily stores data in one HTTP session, localStorage stores permanent data into client hard disk. The advantage is obvious:
Data won't be passed through HTTP request/response, bandwidth will be saved.
There will be no 4KB limitation, web site has much more flexibility to store large data in client.
Note: W3C "recommended 5 megabytes localStorage size limitation per domain", and "welcome feedback", this is much larger than 4KB limitation in cookie.
Now that data won't be passed through network, this will be relatively more secure.
Considering further according to #3, a number of existing HTTPs connection in theory could use plain HTTP by adopting Web Storage, because there is no need to encrypt the data, the data is stored in client side. Since HTTPs usually have only 10% performance comparing with HTTP, eventually either performance will be improved or cost is saved (procuring cheaper server hardware).
So I (personally) would give localStorage a try :). If you want more security you can additionally encrypt your pin before storing it into localStorage e.g. http://point-at-infinity.org/jsaes/