Im' developing an app with ionic/cordova and have used the localStorage for many times.
For example I have such a thing:
window.localStorage['is_user_paid'] = 1;
So, if user pay the money, I set this localStorage item.
Now, if another app set this to 1, and run in the device, does my app assume the user is really paid? Is it necessary to use an app key like 2afjx8y_is_user_paid ? Any idea?
When running under Cordova, localStorage is sandboxed to your app; no other apps can see the content within your app's localStorage, nor can they change the contents. Likewise, your app can only see its own localStorage contents.
Now, sandboxed does not mean not readable/editable by the user, however, which is why it is vitally important not to store things like passwords in localStorage -- the file itself is mostly human-readable and easily accessible by your end user. However, apps are prevented from accessing any localStorage other than their own.
Note: there are ways around this when apps from the same company need to share data, but they involve a different storage mechanism.)
I got around this once upon a time by creating a unique identifier within my app (stored not in the code but in the datastore), and I would use it whenever accessing local storage.
The code is predictable enough, the logic is what's important:
Create a value in your datastore (or a file that isn't readable via a URL, like in the GAE that might be an app.yaml file, or whatever) that you use as unique ID. You can do this by hand if you have to. Generate a GUID of some kind and just store it. Don't put it in your dev code or hardcode it into a JS page, make sure it's off to the side (unless you don't care, but you probably should).
Whenever you access local storage, either to get or put, run it through a function that retrieves that info (or already retrieved it as part of bootstrapping the app, whatever works for your context), and just prepend it to whatever you're calling your key.
That way you can continue coding as if you're just using an easy to understand key, like 'user_name', but the stored/retrieved key will look like "abd12342Baa345324w3423sdfs323DD_user_name".
From time to time, if so inclined, you can change that key, set up your code such that if it retrieves 'user_name' with the old key, you swap it out for the new one and continue your ops as usual.
I did this at work for an app in production and all around it was considered a legit way to go about it. I got the approach from a GAE article that shows how to store and retrieve client tokens for Google Login without putting them in your code; you can even store different versions of that UID for dev/qa/prod and whatever else. It's not specific to GAE, the concept should pan out to any environment.
Of course, if another developer on that project decides to use that same function and same GUID, then the problem just moves. A little discipline can clean that up though, I put in a comment above that util function and we never have a problem.
Related
We have a SPA web application that we're trying to convert into a WinJS project as a native Windows Store app. For most part, the Javascript is working except for DOM manipulations deemed unsafe.
One thing that does not appear apparent is, how can the start page of the app (e.g. index.html) be supplied with query string and hash parameters? Our site main page is designed to behave differently based on parameters.
e.g. index.html?contextId=xxxxx#enviroment=xxxxx
I tried adjusting the value in package.appxmanifest to no avail. It will throw errors on query strings, and hash parameters will silently not persist.
UPDATE: Project background
A brief about what our app does, and then why the above naive desire won't work and the answer below how we went about this issue.
Our web app is a highly-dynamic data-driven application that completely relies on data to figure out what to render. Therefore the ?contextId=xxxxx parameter is so crucial as it tells our system to load the data which further informs what kinds of visual components to load and it goes on recursively to form wildly different UIs.
We were looking to therefore find some means to supply these parameters like traditional command-line parameters to the same executable to produce different UIs. And thus different "apps" by mere changes in those parameters. Like a "config transform" mechanism for web.config in ASP.NET web projects, that would be most welcome.
However further testing showed it is not possible; a single Windows store app project has a GUID that is supplied into the packaged app bundle. Building the same project multiple times with different "build config" would just mean overwriting a previous installation since they are the same app with increasing version numbers. The answer details how we went about this.
Windows Store apps don't work with URI parameters when launched from their primary tile. In that case, you should make sure that the app defaults to suitable values, e.g., if you were thinking to supply defaults in the manifest, then default to those in the app's activation handler for the ActivationKind.launch case when eventObject.detail.arguments is empty.
There are two other ways to launch an app that can supply other arguments.
First is to launch via a secondary tile. When you create the tile from the app (which is subject to user consent), you supply the launch arguments. In your activation handler, for ActivationKind.launch, those args will be in the eventObject.detail.arguments property.
Second is to launch the app through a URI association. You use a custom schema for this, which is declared in the manifest. The app will then see ActivationKind.protocol and eventObject.detail.uri will contain the full URI including any parameters. A URI launch can be done from another app, by entering the URI into a browser address bar, or through a shortcut that a user could configure on the Start screen.
The first step is to convert our Windows (8.1) Store project into a Universal app structure, which would then spin off a separate Windows Phone WinJS project (this is nice when we wish to target Windows Phone later) and a shared project.
Practically everything from the Windows Store project is moved to the shared project (including default.html or index.html). What remains in the Windows Store project is a customised config.js carrying the parameters
window.customWin8 = {
contextId: xxxxxxxxxx,
customParam: 'xxxxxxxxxx'
};
The downstream modules that sense for query string/hash parameters would then fall back to this alternative object if it exists to pick up the data it needs.
Now, for every differing app we wish to deploy, that would for now seem to require a separate Windows Store project so it gets its own GUID and won't conflict with other apps. All these projects would reference the very same shared project thanks to the Universal structure Visual Studio affords. The only down side is it seems Visual Studio 2013 does not have a direct UI method to make this referencing to the share project and has to be hand code into the jsproj file.
<Import Project="..\Common.Shared\Common.Shared.projitems" Label="Shared" />
With this adjustment they can all build and package with their isolated "build config".
What I'm looking to do is have a button on every row of a table that when clicked saves that row to a cookie or HTML5 webstorage (cookies were my initial thought, but it sounds like webstorage might be a better alternative). I'd also like that row to be removed from this table to show that it was selected.
When I or the user is finished selecting different rows, we would then go to a new page that lists all of the data from the cookie or webstorage in a new table.
Tohaku, you idea does not clear where the data is coming, so you will delete/update/save it? but just trying following are suggestions.
If it is coming from database backend server, than simply make table and add button and assign onclick event in javascript with ajax so each row can be deleted from database.
How do you remove that row, simply put class identifier on td column, make java script to remove that td which is deleted. As for saving you don't need as it is already done in your ajax request. So here there is no need to use any web storage.
As question need more explanation, but if in case you must have to use web storage, you should use indexedDB, as webstorage is depreciated and no more being maintain. Another reason is I have also made full app of mobile on web storage but I found that it don't delete columns individual either it can drop whole table but no individual column deletion. IndexedDB also have many issue and support is in only latest versions but safari/ios does not support it so you also need some shiv solutions.
On first run it will retrieve all your data from database, so use javascript function to load on ready stat of page. Now put same two button with javascript so when delete is pressed it will delete row and save is (as no right explanation so will save in another database). IndexDB is nosql database which is based on object, key storing.
How to do it with indexDB read here https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB
I'm currently creating pdf documents server side with wkhtmlpdf and nodejs. The client side sends the html to be rendered (which may include img tags with a source). When the user is previewing the html in the browser the images they uploaded to their account show fine because the user is authenticated via the browser and the node route can simply look up the image based on the user id (saved to session) and image id (passed in each image request).
The issue is when the images are attempting to be rendered in wkhtmltopdf webkit the renderer is not authenticated when it makes the request for images via node's exec of wkhtmltopdf in a separate process. A request to something like GET /user/images/<imageId> will fail due to the session not being set when the request is made inside the headless wkhtmltopdf renderer.
Is there a way to pass authentication via some wkhtmltopdf option or possibly a different way of authentication for images? The only restriction is not making images public.
I asked a similar question a while back that might help you:
Generate PDF Behind Authentication Wall
WKHTMLTOPDF has --cookie-jar which should get you what you need. Note that it didn't for me, and I wound up answering my own question with an alternate solution. In a nutshell, I wound up accessing the page via CURL - much more flexible - then writing a temporary that I converted to PDF, then deleted the temporary file.
A little round-a-bout, but it got the job done.
To implement authentication I allowed a cookie id flag ( with connect the key defaults to connect.sid ) as a query option in my image routes. The only "gotcha" is since images are requested from the server's perspective, you must ensure all your image paths are absolute domain paths rather than relative to your application ( unless those two are the same of course).
Steps for Expressjs:
Setup the id flag middleware which checks for say sid in the query via req.query (eg ?id=abc123 where abc123 is the req.cookies['connect.sid'], or req.signedCookies['connect.sid'] if your using a secret as you probably should )You may need to ensure the query middleware is setup first.
Ensure the req.headers contains this session id key and value prior to the cookie parser so the session is properly setup (eg if a cookie exists append a new one or if one does add it as the first req.headers.cookie = 'connect.sid=abc123;')
Ensure all image paths contain the full url (eg https://www.yourdomain.com/images/imageId?id=abc123)
Some extra tid bits: The image source replacement should probably happen at the server level to ensure the user does not copy/paste the image url with the session id and say email it to a friend which obviously leaves the door open for account hijacking.
I was wondering how to keep images secure on my website. We have a site that requires login then then user can view thousands of different images all named after their ID in the database.
Even though you need to login to view the images the proper way...nothing is stopping a user from browsing through the images by typing <website-director>/image-folder/11232.jpg or something.
this is not the end of the world but definitely not ideal. I see that to stop this facebook just names the images something much more complicated + stores them in hashed folders.
Gmail does a very interesting thing, their image tags looks like this:
<img src=/mail/?attid=0.1&disp=emb&view=att&th=12d7d49120a940e5>
I thought the src attribute has to contain a reference to an image??...how does gmail get around this?
This is more for educational purposes at this point, as I think this gmail scheme might be overkill for our implementation.
Thanks for your feedback in advance,
Andrew
I thought the src attribute has to contain a reference to an image?
GMail is referencing an image. It's just being pulled dynamically, probably based off of that th=12d7d49120a940e5 string.
Try browsing to http://mail.google.com/mail/?attid=0.1&disp=emb&view=att&th=12d7d49120a940e5
Instead of it being a direct path to its location on the server's filesystem, it uses a dynamic script (the images may even be in a database, who knows).
Besides serving up an image dynamically from your webapp, it's also possible to use a webapp to dynamically authorize access to static resources that the webserver will serve -- commonly by putting the files somewhere that the webserver has access to, but not mapped to any public URI, and then using something like X-Sendfile (lighttpd, Apache with mod_sendfile, others), X-Accel-Redirect (nginx), X-Reproxy-File (Perlbal), etc. etc. Or with FastCGI you can configure an application in a FastCGI "authorizer" role rather than a content provider.
Any of these will let you check the image being authorized, and the user's session, and make whatever decision you need to, without tying up a proceses of your backend application for the entire time that the image is being sent to the client. It's not universally true, but usually a connection to the backend app represents a lot more resources being reserved than a connection to the webserver, so freeing them up ASAP is smart.
The code that runs after this GET request is issued:
/mail/?attid=0.1&disp=emb&view=att&th=12d7d49120a940e5
outputs an image to the browser. Something doesn't have to be named with a .jpg or .png or whatever ending to be considered an image by a browser. This is how captcha algorithms are able to serve up different images depending on a value in the id. For example, this link:
http://www.google.com/recaptcha/api/image?c=03AHJ_VusfT0XgPXYUae-4RQX2qJ98iyf_N-LjX3sAwm2tv1cxWGe8pkNqGghQKBbRjM9wQpI1lFM-gJnK0Q8G3Nirwkec-nY8Jqtl9rwEvVZ2EoPlwZrmjkHT7SM32cCE8PLYXWMpEOZr5Uo6cIXz1mWFsz5Qad1iwA
Serves up this image:
So the answer really is to just obfuscate your image names/links a bit like Facebook does so that people can't easily guess them.
I usually don't use Smarty but am in the process of editing a prebuilt app, that uses Smarty for templating. It's super easy to check for the login status, but I have searched the Smarty site, docs and the app vendors docs and cannot find a tag of function to check for the initial user login. We need to pass a message to the user at their first login only.. and instead of writing it out I am hoping there is a tag we can use within Smarty, since it's already being used.
Thanks!
You can not do this by Smarty.
To differ the initial login from a later one, you have to store this information somewere. One aproach would be to use PHP and store it in the user database table (table "user", field "first_login").
The other one would be to store it in a cookie on the client side. But I wount suggest it, for you can not rely on it, as the user can turn of cookies.
So you need to find out, weather your application already stores this information in the user db table. Which it does most likely not. Therefore you need to define the db field and set it after login (using PHP). Afterwards you can user $smarty->assign() in your PHP code to publish your message to smarty in case of first login.