Ember Simple Auth provides a route mixin that lets you authenticate certain routes in your application.
I'm working an app where essentially every route (except the login route) is authenticated. Is is possible to specify this in a single option somewhere, instead of having to include the mixin in each route?
No, that's not possible. The best solution is to add an internal route and move all routes (except the login and index routes) under that route. From the index route's beforeModel you could transition to the internal route when the session is already authenticated.
Related
I use an Express backend with the nuxt.render middleware to consolidate my API, front-end and development environment. So far, everything is going great, but I had some concerns about security concerning my auth setup.
My backend injects its user session into Vuex through a Nuxt middleware. While this works great for restricting access, the source code of those files is always available with a direct GET method. (e.g. if /admin is protected, /_nuxt/admin.js will still be available and will contain the entire source code of that page). Worst even, because of the default preload links put in the head by Nuxt, they will be automatically fetched, even if not logged in.
I understand that there are not a lot of security concerns with this because my admin API calls enforce the auth on the server side, but sometimes (as it is my case), exposing the source code is not desirable.
I have come up with a solution that works great, while being not very elegant:
In nuxt.config.js, I set render.resourceHints = false. I wish I didn't have to do this to benefit from the prefetching of available routes, but there seem to be no way to restrict the selection of prefetched routes.
Before plugging next.render into the Express' middleware chain, I selectively restrict the page's source code. (e.g. app.get('/_nuxt/pages/admin.js', restrict), where restrict is a middleware that returns a 401 if not authenticated, or calls next() if it is. That prevents both XHR fetching and direct GET.)
I make a custom error.vue template, where I catch the error message Nuxt will throw if forced to access a route that the user shouldn't have access to, which looks like Loading chunk 1 failed, and normalize it to a "Forbidden" error page.
Is there a more pragmatic way of doing this that I miss, or is that outside the scope of what Nuxt.js provides at the moment?
I'm currently trying to build an app that needs the user to authenticate with CAS (Centrale Authentication Service) to use it. I'm using Angular 5 for the front-end and Node.js for the back-end.
To authenticate the user on the server side I'm using a module called 'r-cas-authentication' which creates an express-session when the user is authenticated. The fact is I don't know how to check on the Angular side if the user is authenticated and otherwise redirect him on the CAS authentication page.
Do you know how I could do that?
Thanks!
You don't need to deal with this on angular side. Just have the Node server redirect the unauthenticated users to a login page, always. Browser sets the session headers, and your Node server will see there's no auth and send a redirect. The r-cas-authentication module mentions the bounce and bounce_redirect options in the docs, this will further streamline the process.
Your node instance will serve the login page.:
app.get('/login', (req, res) => res.sendFile('path/to/login.html'));
Additionally, your assets (frontend scripts, css, images, etc) are (usually) free to have:
app.get('/assets', express.static(pathToStaticDirectory));
Also, you have authentication endpoint:
app.get( '/authenticate', cas.bounce_redirect );
Next, it needs to serve the Angular app. It will, however, require a cas session here. We target '/home' but it can be another path like '/' or whatever have you.
app.get('/home', cas.bounce, express.static(pathToAngularAppDirectory);
Finally, you will likely have REST API endpoints that you want protected:
app.use('/api', cas.block, appRoutes);
Now, here's what happens. Request comes infrom the browser. It hits the '/home' route. Since the browser is on it'S first visit, there's no authentication headers set. It will hit the cas.bounce() block and get redirected to /login route. Once it goes there, it gets served login.html*.
You enter your login data there and hit Login button - the page gets submitted, and cas middleware authenticates the user - sets the session data and all to browser. Browser will cary these around with it (note I say browser, not Angular). It also redirects the user back to '/home' page.
Now your browser has the session info, so it gets a pass on the route, gets served the Angular files, the app starts normally. All is cool.
There is one more case you might wanna handle from Angular.
Let's say your session expired. And the browser was left open or something. The user revisits the page - all cool, cas.bounce will redirect the user back to login form.
But what if the user simply clicks "refresh" in your app? Then Angular's HttpClient gets a 401 response (as per node module docs). You can have a simple http interceptor that does a window.location.reload() or similar (basically a full page reload, not client-side navigation), and on a page reload, your app get's caught into cas.bounce because it's trying to reload /home unauthenticated.
I am writing a full stack app. I am using front end templating, not server side.
I originally wrote my routes to be api endpoints with restfull standards. So, for instance....on the front end if a user wanted to view their profile I would have the api call out:
router.route('/users/:userId')
.get(isLoggedIn, api.getUserById)
These api endpoints are not public in the manner to be consumed by other apps, they are just for the front end web app to consume.
I am using session tracking to do this, because the user will always stay logged in once they are logged in. I realize that I do not need the user ID number in the api call, because I can just get it from the session object. With that being said, how should I construct the /users/:userId route? I no longer need the :userId because I can get it from the session object. But if I did something like /profile it looks crummy and not to restful standards(even though I am doing session tracking so it is statefull).
What would be the best way to make the route for best practices? /profile or /users/:userId even though I don't need :userId?
How do I implement CSRF protection using built-in Express middleware for HTTP GET requests?
For instance, user logout often made via GET request and actually change state of web application so it should be protected against CSRF.
Unfortunately, CSRF middleware ignores HTTP GET and doesn't export helpers to manually check token.
BTW, they now expose the way of explicitly setting which methods to ignore
app.use(csurf({ignoreMethods: ['HEAD', 'OPTIONS']}))
You could create a custom fork of the Connect CSRF middleware that would not ignore GET requests. The line that does so is here: https://github.com/senchalabs/connect/blob/master/lib/middleware/csrf.js#L76
However, don't do it. GET requests are safe and idempotent: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
In other words, no one is worried that a malicious web script might log them out from a site. The worry is that it could post spam in your name or transfer money out of your bank account. That's what you need CSRF to protect against. Lots more info here: http://en.wikipedia.org/wiki/Csrf
I'm using Express to build a web site. I'm serving static files and have a REST API. For the static files I'm using the session middleware to restrict certain pages to logged in users. The downside to this is that the REST API has cookies in the HTTP header. Can I restrict certain routes to not use cookies? Is this what the mount function is for?
Well, if you're setting or requiring cookies, you must be using some sort of middleware function to do so (since there's nothing in Express per se that would do it). If you wrote the middleware function yourself, you just need to rewrite it to be a little more picky about when to set/require cookies. If you're using a pre-written middleware function, try putting it later in the stack than any route functions that shouldn't be requiring cookies (this will generally mean putting app.use(express.router); ahead of any app.use(...) call that invokes a cookie-dependent middleware function).
If this doesn't make sense to you, please post what you're doing (after stripping it down to a minimal test case).