nginx-gridfs: control which documents in a collection can be served via nginx vs my app? - mongodb

I'm doing some planning for replacing an existing solution with mongodb and potentially using the GridFS functionality for static assets. One question that I have is if I choose to front GridFS with nginx, is there a way to control which assets in a collection may be served directly from nginx versus which asset requests need to be directed to my application?
The reason I ask is that some security checks are done for certain assets and those assets have always been served out of the app itself (and will need to continue to be, at least for now).
I was thinking, I could probably just add a property on the file descriptors stored in nginx that is something like isPublished. Could I instruct nginx-gridfs to respect this property?

Looks like there have been requests for this functionality but the project is largely abandoned by contributors. The applicable ticket is here: https://github.com/mdirolf/nginx-gridfs/issues/24

Related

What is the best way to link an image with a mongodb item?

I'm currently building my first real project that includes Express and MongoDB. Since it's one of the first backend-heavy projects I've worked on outside of my Udemy course, I've run into a lot of questions.
My project is supposed to be a mock-online store that would display items I have created inside of my MongoDB server. The problem I'm having is that I don't know the proper way of serving those image files that should be associated with each item (such as the image of a hat, for a hat item). I could add them directly into the project's public folder, but I don't know if that would be feasible in terms of the scalability that I want this project to demonstrate. But it doesn't seem like MongoDB will let me store images within each item. How would I go about doing that?
Sorry in advance if any of this is unclear, it's my first time posting as well. I'll try and provide more information if I need too. Thanks!
If you want a scalable solution for images, you typically would use a separate service like AWS S3 or Imgix.
There are several benefits to using a 3rd party service. You don't bog down your web server with image requests, or image resizing. You get virtually unlimited space. Etc.
In your MongoDB document, you would then store a key like /item/1.jpg or whatever, rather than the image itself. Your front-end then uses the key to request the image when someone visits your website.
If you want a turn-key solution, I recommend starting with Imgix (or Cloudinary, or some similar service). It is more expensive than S3, but it is pretty cheap for a small project, and it will get you up and running a lot faster.

When you have 2 sites, front end and a rest api, how/where do you store uploaded images?

I have 2 different sites basically. 1 is a rest api, the other is the front end built in vue.
Actually uploading a file isn't the issue. My question is how to have the Vue portion access the files that were uploaded via rest.
Should I save the files to c:...VueProjectFolder\images (could use some code help if this is the case)? Or should the Vue site be inside the rest api folder for relative access? Or is it better to save relative, then move the uploaded files? Or do I have vue access the files via the rest api address?
None really seem like the right answer and I'm failing with google atm.
Down the road, I would expect them to be served from a mapped drive as there will be many. Mostly images, but also sound files.
This is probably not a Vue or 'two sites' issue. This is an architecture issue, and like such issues, It depends. What I can do is tell you how I approached a similar situation.
I uploaded the files normally
I renamed them, created a folder structure based on the year, month, and day the picture was uploaded. Then I moved the image to the permanent location. So an image uploaded today will be located at .../assets/images/2020/09/01/randomImageName.png for instance.
I stored the image location along with whatever resource came with the uploaded image in the database.
Now in my frontend, I do a normal api call for a particular resource and it spits out everything about that resource, including the image location.
I think I should point out that my case was an ecommerce website with a REST API endpoint servicing the frontend requests. Generally this approach is advised since you can take advantage of backing up the image directory, backing up the database and easily moving between servers if need be.
This may not exactly be your case, but I hope it gives you insight into how to approach this efficiently.

Run multiple sites on the same GWT application

Can someone please point me to the right direction.
I need to be able to host my GWT application in a way that it allows multiple clients to use the same application which could be separated by url's but internally using the same application.
the different sites would probably be seperated by different configurations. eg. different database, different log path etc, etc,
any ideas.?
You could use the following way to arrange your projects :
- my.application.core.project : it holds all the business logic and views for the application except for the entry point
-my.application.customerX.project : it holds only the entry point and the property files used for having the connection to the db, probably customerX specific theme
-my.application.customerY.project : it holds only the entry point and the property files used for having the connection to the db, probably customerY specific theme
Such an organization of the projects would allow you to have a common core that is distributed to each of the customers and also the ability to build on top of the core customer-specific impelementations.
The url's per client can be done with URL rewriting. Be it with an apache server in front of your application and/or in combination with a Filter in your web application.
As for the configuration, logging, and/or database per client you want a solution that doesn't store a file per client on the file system next to your application. Preferable you store client specific settings in one database and have an admin interface to manage it. For the client's data you also don't want a separate database per client, because it doesn't scale well, and would be a maintenance mess if you need to upgrade your application and databases to a newer version. Look for a multitenant architecture.
I admit this is a vague answer, but without specific system and software descriptions it's kind of hard to give a concrete answer. Nevertheless I hope this answer does give you some direction.
I have successfully achieved this by setting up separate directories in tomcat for different clients and then creating soft-links to the main application within that folder. when it comes to database connection properties and other configuration properties, instead of pointing them to the main application I just created them separately.

Web development, protecting application code

I'm looking at some (PHP) Frameworks, and I just noticed this in the Laravel documentation:
Like most web-development frameworks, Laravel is designed to protect your application code, bundles, and local storage by placing only files that are necessarily public in the web server's DocumentRoot. This prevents some types of server misconfiguration from making your code (including database passwords and other configuration data) accessible through the web server. It's best to be safe.
I'm familiar with CodeIgniter and CakePHP, as far as I know, these two frameworks don't do this. Should you really split it up and place your core logic outside of the webroot? In my experience, most clients use shared hosting and are not able to change their VirtualHost settings.
What kind of misconfiguration could you possibly do that would output your passwords? When developing, should you really do this?
Yes, keeping only those files which should be publicly accessible in DocumentRoot is a best practice for web application security. Consider:
Every file which is private would need a rule configured with the web server to explicitly block it.
Anyone adding files to the project needs to consider web server security settings. Simply keeping the files in separate directories makes it obvious what's public. And developers don't need to change security configurations.
Separating executable code and static files is a good practice anyway.
Not blocking access to PHP scripts can cause unintended consequences. For example, you may have a script to update some DB records when run manually at the command line, so someone simply guessing a script name can run it over the internet.
Monitoring for and cleaning malicious code written to the public directory is much easier if the real application logic is elsewhere. See Wordpress breakins for an example.
CakePHP supports this - see deployment:
CakePHP applications should have the document root set to the
application’s app/webroot. This makes the application and
configuration files inaccessible through a URL.

How do I sync an offline web app (HTML+JS+CSS) with my server?

Do I need to implement my own sync methods in order to make an offline web app (html+css+js) stay up to date with changes made on the server (and viceversa)? I'm using MySQL on the server side.
I read Two-way sync between iPhone application and web application with some pointers but I think they're talking about native applications when they mention CFUUIDCreate and I wander if this is possible for the Web.
Does someone have some code to share or maybe can point me in the right direction?
Thank you!
P.S.: I hope my english is not that rusty ;)
To store static contents on the client-side, as Jethro Larson said, the Application Cache Manifest is the way to go to cache the static contents of your website (HTML, CSS, JS and images).
To handle dynamically generated contents offline, you can use javascript templates. There are several solutions for this.
To sync the two databases, there is a project called persistence.js (persistencejs.org) which is a javascript library which offers a unique API to work with WebSQL databases, Local Storage, etc. They have a plugin for this library called persistence.sync (persistencejs.org/plugin/sync) which syncs the remote database with the server's one. It consists of POST and GET requests to a specific url that you can configure (for example yourapp.dev/sync). They have an example back-end written in node.js and here is one for Rails. It's simple to understand and persistence.sync is well documented.
Look at the offline cache:
http://www.webreference.com/authoring/languages/html/HTML5-Application-Caching/
http://www.google.com/search?q=offline+cache+html5
http://www.slideshare.net/search/slideshow?q=offline+cache