I am trying to implement the passport local authentication in my backend. It is a todo app which is built with the help of the MEAN stack. Unfortunately, I am facing some problems implementing it. The folder structure is
In Controllers folder, the controllers for the various routes are present.
In routes folder, the file "api.route.js" contains the main route. I want to implement authentication here such that no further routes can be accessed if the user is not autheticated.
In the api subfolder, the different routes are configured.
In the config subfolder, the passport local strategy is defined.
Another new problem I have noticed is that the routes after todo are not detected.
Example : localhost:3000/api/todos
localhost :3000/api/todos/login
route does not work. It says Error 404. Every other sub routes are the same. Any help which will help me to implement will be appreciated. The github profile for this project is :
https://github.com/AritraWork97/TODO-FULLSTACK
The main folder is Todo Backend, it contains the backend code
To, protect routes in back-end I think express-jwt will be handy.
Initialize it like this,
const jwt = require("express-jwt");
const auth = jwt({secret: jwt_secret});
Then put the auth middleware before a route that you want to protect.
router.get("/secret/:uid", auth, profileCtrl.secret);
Related
On my node-express back-end, I want to always serve my Angular files UNLESS it is an API route. If it is an API route, then deal with it as such.
All API routes are protected, except /api/signin, /api/changepass.
How do I structure my code? I think the order of my code is wrong... I keep getting back an UnauthorizedError: No authorization token was found from express-jwt.
Currently my code:
app.use(jwt({secret: secretKey}).unless({path: ['/api/signin', '/api/changepass']}));
app.use('/', [
AuthRouter,
StructureRouter,
DataRouter,
ResultsRouter,
]);
// Serve angular unless it is a path for the acme-challenge for let's encrypt certificate
app.use(ServeAngular().unless({path: [/\/.well-known\/acme-challenge/i]}))
app.use(/\/.well-known\/acme-challenge/i, express.static(path.join(__dirname, '.well-known', 'acme-challenge'), {dotfiles:'allow'}));
"want to always serve my Angular files UNLESS it is an API route"
Instead, you should return your Angular app on the root path or on a static path if called via HTTP GET method and let hash routing handle the routes in Angular. Node doesn't bother hash routing, so you could use them to navigate through your app.
Anyway on error you could redirect on error or login page
"All API routes are protected, except /api/signin, /api/changepass"
redirection, authentication and protection should be handled by express's middleware function (https://expressjs.com/en/guide/using-middleware.html) in order to ensure authentication or redirection. Your application shouldn't be aware of which route should be protected or not.
"I keep getting back an UnauthorizedError: No authorization token was found from express-jwt"
On your Angular code have you created the required interceptors in order to forward on each request the required jwt (as cookie or header)?
I am trying to use the jwt express middleware as well as the postgraphile middleware together, and I want to add an exception for having an auth token to the graphiql interface. I know that postgraphile starts up graphql on /graphql and graphiql on /graphiql unless otherwise configured. So in my jwt middleware init I am doing this:
app.use(jwt({ secret: process.env.JWT_SECRET}).unless({path: ['/', /\/graphiql/i, /\/graphql/i, /auth/i]}));
Which makes it so /graphiql, /graphql, and /auth routes do not require an auth token. This appears to work fine because I can get to the graphiql interface just fine, and the graphql queries I'm building are working just fine. However, in my express terminal, there is still something that it's trying to connect to that is throwing a No authorization token found when I load http://localhost:3000/graphiql
Any thoughts on what else it might be trying to hit that I will also have to add to the unless() method in the JWT middleware?
PostGraphile currently loads the GraphiQL assets (JS, CSS) from /_postgraphile/*, so you probably want to whitelist those assets.
Another approach is to mount postgraphile before you add the jwt middleware - that way it will be unaffected by it and you won't need to maintain a .unless list.
app.use(postgraphile(...));
app.use(jwt(...));
app.use(...);
I'm a beginner in Express framework and having some difficulty with the code flow. I have following code in app.js
app.use('/', index);
app.use('/login', login);
app.use(require('./routes/authenticate_user'))
app.use('/user', userDetails);
Problem is that If a user enters an invalid route suppose '/wrong' then my middleware sends the response for that instead of app throwing 404 Not found. Is there something I'm missing?(looks obvious). Thanks for any help.
There are a couple choices for how/where you run the authentication middleware.
1) You can run it immediately after any non-authenticated routes have been defined. This will give you a non-auth error for any route, whether it's a real route or not other than the few routes that the user is allowed to go to without authentication.
2) You can manually add the middleware to each defined route that is supposed to have authentication such as:
app.get('/something', yourAuthMiddleware, yourRouteHandler);
This will run the auth check only on routes that are actually defined. This allows you to give a 404 rather than an auth error for routes that are not defined.
The advantage of the first option (which is essentially how you have it now) is that a non-authenticated user doesn't even get to find out which routes are defined or not. If they're not authenticated, they don't get in at all except to the couple of routes that they are allowed to. In my opinion, this is the right design.
The second option will let you give a 404 for a route that isn't defined, but it requires manually adding auth to each route or each router that you define that needs auth. This allows a non-authenticated user to find out which routes are defined and which ones are not.
I am totally new to everything Nodejs/express/angular, and I just ran into a question that bothers me.
When you have a MEAN stack, it seems that routes can be handled by both Express.js and Angular.
Angular:
For instance, if I define a route in Angular, I can do it like this:
var app = angular.module("app", []).config(function($routeProvider) {
$routeProvider.when('/login', {
templateUrl: '/templates/login.html',
controller: 'LoginController'
});
$routeProvider.when('/front', {
templateUrl: '/templates/front.html',
controller: 'FrontController'
});
$routeProvider.otherwise({redirectTo: '/front'})
});
But with express.js I do:
app.get('/',function(req,res){
res.sendfile('templates/angular.html');
});
So my question is:
When do you use angular routing, and when do you use express routing?
(I might miss something very obvious here, but I hope you can point it out)
Those two serve different purposes on a single page app.
The app would do all the CRUD (endpoints where you create/read/update/delete your stuff, for example: projects, users, bills, etc). Also it would do all the authentication stuff (like /login and /register).
All of that needs routes, because you would want something like /api/users to grab all your users. All those routes, AKA CRUD routes and authentication routes goes into express.js router. Why there? Because those are routes of the backend.
On the other hand, you have your angular application, which contains the visual part of your application and there you want some routes. You want / to point to your home, you would want /users to have a page where you list your users or even /users/add to have a page with a form to add new users.
You could see it this way:
Backend routes (express ones): Those are the routes that an end user won't have to know about or even use them (your angular app will use them to communicate with the backend to work with its data but an end user wouldn't put them directly on the browser)).
Frontend routes (angular ones): Are the routes that maps to different pages of your application and because of that, end users can use them to access some parts of your application directly.
I'm facing the following situation. In order to further modulize my software development, I've written a few standard modules stand alone. Think for instance of an login module based upon Express and Passport, allowing users to login with all kinds of social services. The module also contains UI for user management, login, registration, profile, etc.
Now, the thing I'm trying to do is to just drop the Auth app folder (containing the express app, all it's routes, views, models, settings and dependecies) into another Express app (for instance, a CMS) and then load it with something like require('./lib/auth/app.js'). I know this is possible, take a look at Kue.
How would I go about doing this? And how do I manage namespacing problems? I could of cours append /auth/ to each route, but I can imagine the settings (app.use()'s) and public folder would conflict with the 'parent' app.js' settings and public folder.
Thanks in advance,
Fabian
Think I found my answer. So, I found this question, and this one. Guess my terminology was off.
I solved my problem by doing a few things. First of all, I changed all routes and url's to be "namespaced" (not really, but this does the job). All routes now have /auth/ in front of them. I did the same to all links, so that's all working.
Next, I removed the server part from my app.js. So, in stead of doing:
require('http').createServer(app).listen(app.get('port'));
I just do:
module.exports = app;
And I add some custom methods to the app object:
app.isLoggedIn = auth.isLoggedIn;
app.notLoggedIn = auth.notLoggedIn;
Then, in my root app, I just do the following to load the auth app in. Routing, public files, and all other stuff happens magically. pretty cool.
var auth = require('./vendor/auth/app');
var app = express();
app.configure(function() {
app.use(auth); // use our auth app
// do a lot of root-app related stuff...
});
Things still to do:
My auth app uses some session stuff. According to the second link, if I understand correctly, the app.use(session...) stuff in my auth app gets overridden by app.use. Also, I want to define an EJS helper to generate my urls (something like site_url('/facebook/callback') which then points to /auth/facebook/callback). Finally, I need to include settings from my root app. I'm thinking of wrapping my entire app.js (in auth) in a function, to which I pass a config object. Like this:
module.exports = function(config) {
var app = express();
app.set('config', config);
// various app settings, routes, etc
// return app so it's available in my root.
return app;
}
I hope this helps, if you need a bit more information I'll see if I can post some code to a gist. just let me know!