Placement of express static files - express

I was building authentication for my webapp when I ran into an error. It happened to do with the express static files . Does it matter where this line,
app.use(express.static(path.join(__dirname, 'client/dist')));
is placed in my server.js because if I place the above line above my app.get('/)
request , my authentication does not work.
Any help is appreciated!

Does it matter where this line is placed.
Yes, it does. Router handlers are processed in the order they are defined and the first one that matches, gets the first crack at the incoming request.
If you have a route that would match something in your express.static() line of code, but you want that to be matched by your app.get(...), then you have to either put the app.get(...) route definition before the express.static() or change things (url paths or available files in the static directory) so the app.get(...) route can never be matched by your express.static() middleware.
We could help explain in more detail if you showed the actual URL you are using and then we can discuss what exactly that URL might be matching via the express.static() line in your client/dist directory.

Related

Why isn't this web site substitution rule not working?

I have an agent that sends out a url to a file. In order to hide the specifics of where that file exists, so I thought I'd create a Web Site substitution rule. So instead of the full url to this file, I decided to send out the following url in an email:
https://< website >/Terms/n=< file name >
I created a Web Site Rule that would map this url to the full url containing the location of the file. The rule is as follows:
RULE: Substitution
INCOMING URL: /Terms/n=*
REPLACEMENT: /db.nsf/< view unid >/< document unid >/$FILE/*
I'm getting a 404, File not found or unable to read file. The full url is good -- I know that because I displayed in the agent log and checked it. Any ideas why this is not working?
thanks
Clem
Thanks Per for trying it out and determining that it SHOULD work. I looked at everything in detail and found that in my Rule had a typo. I actually had double-quotes instead of an asterisk! So I had /Terms/n=" instead of /Terms/n=*. Can't believe I missed that.
Thanks!
clem

prevent handling of missing files by other use/get in express

I'd like to keep the contents of the folder /public for use of local files by a local app. However, when a file is missing, instead of getting the 404, the user is getting the index.html page.
What I would like to do is have user get the 404 when accessing any resource that does not exist for anything under /public/*, but have the react app handle everything else from index.html
this is my setup:
app.use('/public', express.static(path.resolve(myPath, 'public')));
app.get('*', (req, res) => {
res.sendFile(path.resolve(myPath, 'index.html'));
}
should the get include a regex to not include public matches, or is there a way to handle this with use?
The problem is that you've explicitly told express to look into your public folder for ANY file that the user requests with this line:
app.use('/public', express.static(path.resolve(myPath, 'public')));
Express, by default, serves NO files. It makes nothing public by default. So, the first thing to do is to remove the line of code that makes that entire directory public. And, then if you want to serve some specific things from that folder, you need to either make very specific routes to only the files you want to be public or you need to move the "public" files out to a directory where everything can be public and then point express.static() at that directory.
Then, you've added another line to respond to any request possible with one file:
app.get('*', (req, res) => {
res.sendFile(path.resolve(myPath, 'index.html'));
}
This is just not really how you should be using express at all. Here are some steps to think through:
Figure out which static files you want Express to serve automatically (without a specific route being made for each file).
Then, organize those files so they are in their own sub-directory on your server hard drive.
Then, you can point express.static() at that directory without any fear of it serving files you don't want to be automatically public.
Think about organizing things into a hierarchy (not required, but sometimes simpler to manage) so that css files might be one place, client-side js another place, etc... such as /css/css files here and /js/js files here when laying out your hierarchy. Then, you can control the serving of each type of file separately if wanted and it may make maintenance easier (since separate people often maintain CSS files and JS files).
Then, design specific routes you want handled for other types of files.
Then, add an error handler route which determines what should be returned to the browser when no other route handler was found. How to do that is described here. Also, note that Express has a different default error handler based on whether the NODE_ENV environment variable is set to production or not.
Don't use * routes that handle everything with the same content, including things you don't want to provide a specific page for. You don't want search engines to index things that you don't have original content for and you don't want users to bookmark unintended URLs just because you happen to be using * in a route handler.
I was able to resolve it by adding
app.get('/public/*', (req, res) => {
res.status(404).send(req.path + ' not found');
})

AspNet Core router added extra URL segment

I have been running into the issue where the AspNet Core router will add an extra segment to the URL when there is an error.
For Example:
The UseCookieAuthentication will redirect to /login but if there is an error then the router will direct me to /login/login with an error page, and if I continue going to the root URL "http://localhost:59093/" more segments will be added (i.e. http://localhost:59093/login/login)
Found the answer on here.
It seems that when app.Map is used it rewrites the PathBase with the matching path in app.Map and if there is an error thrown it keeps appending to the PathBase.
This issue does not occur when using app.MapWhen and you get more control so this is how I fixed the issue.

Seeing bundle files path in login url and redirecting multiple times

I'm using mvc4 and .Net 4.5 in my project with SSL. Now, on localhost and even on server, the login page gets redirect a bunch of times and then loads without and css on page. In browser debugger I get error as:
Uncaught SyntaxError: Unexpected token <http://localhost:55248/Account/Login? ReturnUrl=%2fbundles%2fjqueryval%3fv%3dWrBNyT_GYLXAZ7iWD7vDdFccq24m7v_9MPi3rcQ8FO01&v=WrBNyT_GYLXAZ7iWD7vDdFccq24m7v_9MPi3rcQ8FO01...
I'm using bundling and code snippet as below.
bundles.Add(new ScriptBundle("~/bundles/BaseJs")
.Include("~/Scripts/jquery-{version}.js")
.Include("~/Scripts/jqueryui/jquery-ui.js")
.Include("~/Scripts/bootstrap.js"));
The syntax error is from the error page being loaded as JavaScript (when it's obviously not JavaScript). It's a red herring. The true problem is that your JavaScript file is needing authorization in the first place.
Typically, this wouldn't be an issue. By default, anything with an extension (.js, for example) is ignored by MVC and handled directly by IIS. Worst case scenario, there, IIS doesn't have permission to read the file, and you end up with a 403 Forbidden. It would end there, as an IIS-level 403 would not trigger a login page redirect, mostly because, again, MVC is not involved.
However, if you've bungled around the with default setup, such that MVC is now handling all requests, even for static files. Then, the action that's being triggered to handle the request to your JavaScript file is requiring authorization, and therefore is redirecting to the login page. So find out what action is being hit and either remove the requirement for it to be authorized or have the right action serve the file. Or, ideally, leave things as they should be and let IIS do what IIS does best and serve the static files.
EDIT
I wasn't paying attention to the fact that bundles are rendered without a file extension. However, the steps to correct the issue are largely the same. Something is mostly likely off with your routing, and the request for the bundle is actually being caught by one of your actions, particularly one that requires authorization. Look out for catch-all routes and make sure that you're not using a route like "bundles" anywhere in your RouteConfig.cs or any of your Route attributes, if you're using attribute routing.
First try to include your bundles like that :
.Include( "~/Scripts/jquery-{version}.js",
"~/Scripts/jqueryui/jquery-ui.js",
"~/Scripts/bootstrap.js"
);
Include takes string[] as parameter and you don't need to call include for each row. Then you should debug your bundles to see which js is giving the error.
Try to comment out rows 1 by 1 to see what would be the result. The problem is definatelly in your bundles, I also had these kind of errors. If you can provide more code - > snippet from the view, of the css loading and bundles and stuff like that I would be able to help you more.

Tell Apache not to freak out over 404, and allow Ember-CLI router/adapter logic handle slug in URL

My new Ember-CLI app uses a user portal slug in the URL to display proper information to the user. For example (fake URL): http://my.server.portals.com/robertplant
I'm using a combination of router and adapter logic to get the user portal name form the url slug, and then display the data related to it. It probably needs some more work, but here's what I have so far:
Router code extract:
Router.map(function () {
this.route('portal', {path: '/:portal_slug'}, function () {
this.resource('account', {path: '/'});
});
});
Adapter code extract (for hitting the right API end point based on portal):
namespace: function () {
var portal = window.location.pathname.match(/^\/([^\/]*).*$/)[0];
return 'abc' + portal + '/api/v1';
}.property().volatile(),
I can hit the app locally (e.g.: http://localhost:4200/robertplant/) with no issues. It runs using Ember-CLI’s built in web server.
However, when I move the app to the server, which runs Apache, and try to hit it (e.g.: http://my.server.portals.com/robertplant), I get:
Not Found
The requested URL /robertplant was not found on this server.
Which makes sense I suppose, since there isn’t really a directory named the same as the slug. However, there has to be a way, I would think, to tell Apache to ignore the problem it thinks it is having, and allow the app router to handle it. The local web server is doing it somehow.
Ideally, the solution would leave the URL displayed the same. Also, re-writing the request to point to something like http://my.server.portals.com?slug=robertplant causes Ember-CLI assets to be looked for at the wrong path (can't set baseUrl dynamically).
I'd appreciate any feedback on how to set up the app in Apache to allow for this to happen.
Solution:
Say the current subdomain is my.portal.com. Create another subdomain that points to the same directory on the server. Name it my2.portal.com
For the first subdomain, add a mod rewrite rule which rewrites something like
http://my.portal.com/joe_blow
as
http://my.portal.com?portal_slug=joe_blow
This allows you to hit the url without a 404.
Set the asset paths (in the generated index.html) to point to the second subdomain. E.g.:
http://my2.portal.com/assets/app_name.js
This allows the app to find the assets without the issues associated with the rewrite or the slug in the url.
Of course, you can also place the assets anywhere else, including an S3 bucket. But in my case, I have a constraint of having to store them on the same server/network for security reasons. And my way you can deploy all the files to the same location.
That's it! Works like a charm.
The only thing I'm not fond of, is having to edit the index file after it's generated. I will try to automate it at some point.