0

In my express application, I have defined a series of routes as follows:

import express from 'express';
import passport from 'passport';
import authStrategies from './auth.strategies';
import authController from './auth.controller';
import authService from './auth.service';

let router = express.Router();


router.post('/', authController.create);
router.get('/login', authController.redirectToLogin);
router.post('/login', authController.loginLocal);
router.get('/', authService.verifyOrdinaryUser, authService.verifyAdmin, authController.index);
router.delete('/:id', authService.verifyOrdinaryUser, authService.verifyAdmin, authController.destroy);
router.get('/me', authService.verifyOrdinaryUser, authController.me);
router.put('/:id/password', authService.verifyOrdinaryUser, authController.changePassword);
router.get('/:id', authService.verifyOrdinaryUser, authController.show);
router.get('/google',
    passport.authenticate('google', {
        scope: ['profile']
    }));
router.get('/google/callback',
    passport.authenticate('google'), authController.googleCallback);
module.exports = router;

I added this router to my application in server.js:

'use strict'
// import the required modules
import express from 'express';
import passport from 'passport';
import config from './config/config';
import logger from 'morgan';
import cookieParser from 'cookie-parser';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
import path from 'path';
import auth from './auth/index'

// connect to db
mongoose.connect(config.db.url, {
    useMongoClient : true
});

// initialize the required variables
let db = mongoose.connection,
    app = express();

// log db connection status
db.on('error', console.error.bind(console,'connection error.'));
db.once('open',() => {
    console.log('Successfully connected to server');
});

//set application variables
app.set("port",config.server.port);

// add middleswares
passport.serializeUser(function(user, done) {
    console.log('serialize ',user);
  done(null, user._id);
});

passport.deserializeUser(function(id, done) {
    console.log('deserialize ',id);
  done(null, id);
});
app.use(passport.initialize());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname,'client')));

//add routes
app.use('/auth', auth.router);
app.use('/', (req, res, next) => {
    res.status(200).json({message : "success"});
})

module.exports = app;

Now when I send a GET request to /auth/google it goes to all the routes in the path, this is my Morgan log:

GET / 200 6.457 ms - 21
GET /auth/google/callback?code=4/rWjEEB8ZqatELaIYVJTsdg4uBruX3tihoqfh33t54sw - - ms - -
TokenError
    at Strategy.OAuth2Strategy.parseErrorResponse (/Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:329:12)
    at Strategy.OAuth2Strategy._createOAuthError (/Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:376:16)
    at /Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:166:45
    at /Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:191:18
    at passBackControl (/Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:132:9)
    at IncomingMessage.<anonymous> (/Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:157:7)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
GET /auth/ 403 7.344 ms - 2105
Error: No token provided
    at exports.verifyOrdinaryUser (/Users/dhanushu/Work/Projects/journal/dist/server/auth/auth.service.js:37:19)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at /Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:281:22
    at Function.process_params (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:174:3)
    at router (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:317:13)
    at /Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:335:12)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:275:10)
    at SendStream.error (/Users/dhanushu/Work/Projects/journal/node_modules/serve-static/index.js:121:7)
GET /auth/google/callback?code=4/rWjEEB8ZqatELaIYVJTsdg4uBruX3tihoqfh33t54sw 500 355.270 ms - 1230
TokenError
    at Strategy.OAuth2Strategy.parseErrorResponse (/Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:329:12)
    at Strategy.OAuth2Strategy._createOAuthError (/Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:376:16)
    at /Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:166:45
    at /Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:191:18
    at passBackControl (/Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:132:9)
    at IncomingMessage.<anonymous> (/Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:157:7)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
GET /auth/google 403 1.138 ms - 2101
Error: No token provided
    at exports.verifyOrdinaryUser (/Users/dhanushu/Work/Projects/journal/dist/server/auth/auth.service.js:37:19)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at /Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:281:22
    at param (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:354:14)
    at param (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:410:3)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:174:3)
    at router (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:317:13)
    at /Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:335:12)
GET /auth/google/callback?code=4/rWjEEB8ZqatELaIYVJTsdg4uBruX3tihoqfh33t54sw 500 340.907 ms - 1258
TokenError: Code was already redeemed.
    at Strategy.OAuth2Strategy.parseErrorResponse (/Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:329:12)
    at Strategy.OAuth2Strategy._createOAuthError (/Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:376:16)
    at /Users/dhanushu/Work/Projects/journal/node_modules/passport-oauth2/lib/strategy.js:166:45
    at /Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:191:18
    at passBackControl (/Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:132:9)
    at IncomingMessage.<anonymous> (/Users/dhanushu/Work/Projects/journal/node_modules/oauth/lib/oauth2.js:157:7)
    at emitNone (events.js:91:20)
    at IncomingMessage.emit (events.js:185:7)
    at endReadableNT (_stream_readable.js:974:12)
    at _combinedTickCallback (internal/process/next_tick.js:74:11)
    at process._tickCallback (internal/process/next_tick.js:98:9)
GET /auth/google 403 0.517 ms - 2101
Error: No token provided
    at exports.verifyOrdinaryUser (/Users/dhanushu/Work/Projects/journal/dist/server/auth/auth.service.js:37:19)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:137:13)
    at Route.dispatch (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:112:3)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at /Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:281:22
    at param (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:354:14)
    at param (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:365:14)
    at Function.process_params (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:410:3)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:275:10)
    at Function.handle (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:174:3)
    at router (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:47:12)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:317:13)
    at /Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:284:7
    at Function.process_params (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/index.js:335:12)

But for all other routes, it is working correctly.

POST /auth/ 200 159.107 ms - 1292
GET /auth/me 200 10.090 ms - 129
GET /auth/5991385d081fb00b1b106422 200 4.367 ms - 52
POST /auth/5991385d081fb00b1b106422/password 200 2.339 ms - 21

If I place the /google route as the first one in the router file, then it is working correctly. I am stuck on solving this issue.

Similarly, as we can see there is no route called /auth/logme but when I try to access that route instead of returning a 404 it is throwing up the following error. I am on this for several hours but I couldn't figure out the reason.

GET /auth/logme 500 20.329 ms - 1930
CastError: Cast to ObjectId failed for value "logme" at path "_id" for model "User"
    at MongooseError.CastError (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/error/cast.js:26:11)
    at ObjectId.cast (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/schema/objectid.js:147:13)
    at ObjectId.castForQuery (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/schema/objectid.js:187:15)
    at cast (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/cast.js:229:32)
    at Query.cast (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/query.js:2742:12)
    at Query.findOne (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/query.js:1354:10)
    at Function.findOne (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/model.js:1343:13)
    at Function.findById (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/model.js:1271:15)
    at exports.show (/Users/dhanushu/Work/Projects/journal/dist/server/auth/auth.controller.js:44:23)
    at Layer.handle [as handle_request] (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/layer.js:95:5)
    at next (/Users/dhanushu/Work/Projects/journal/node_modules/express/lib/router/route.js:137:13)
    at /Users/dhanushu/Work/Projects/journal/dist/server/auth/auth.service.js:33:17
    at /Users/dhanushu/Work/Projects/journal/node_modules/jsonwebtoken/verify.js:27:18
    at _combinedTickCallback (internal/process/next_tick.js:67:7)
    at process._tickCallback (internal/process/next_tick.js:98:9)

    at Function.findOne (/Users/dhanushu/Work/Projects/journal/node_modules/mongoose/lib/model.js:1343:13)
Matheus Lacerda
  • 5,983
  • 11
  • 29
  • 45
Dhanushu Uzumaki
  • 183
  • 1
  • 14

1 Answers1

0

Let's solve the problem one by one. Express router is a regular expression, and matches url by router order. So the order of router is very important.

/auth/logme matches router.get('/:id'). /auth/google also matches router.get('/:id')

You should first change the order of router like below.

router.get('/google/callback',
    passport.authenticate('google'), authController.googleCallback);
router.get('/me', authService.verifyOrdinaryUser, authController.me);
router.get('/google',
    passport.authenticate('google', {
        scope: ['profile']
    }));
router.get('/login', authController.redirectToLogin);
router.get('/:id', authService.verifyOrdinaryUser, authController.show);
router.get('/', authService.verifyOrdinaryUser, authService.verifyAdmin, authController.index);
router.post('/login', authController.loginLocal);
router.post('/', authController.create);
router.delete('/:id', authService.verifyOrdinaryUser, authService.verifyAdmin, authController.destroy);
router.put('/:id/password', authService.verifyOrdinaryUser, authController.changePassword);

So that /auth/google now matches router.get('/google') Related question: Order of router precedence in express.js

If you want 404 for /auth/logme

router.get('/:id', (req, res, next) => {
  if (req.params.id === [ALLOWED_PARAMS]) {
    next();
  } else {
    res.status(404).send('NOT FOUND');
  }
}, authService.verifyOrdinaryUser, authController.show);
ZeroCho
  • 1,358
  • 10
  • 23
  • Hi I made the change you suggested and the /auth/google/ issue is now resolved but /auth/logme is not returning a 404, since it matched /auth/:id. Is there a way to resolve this? – Dhanushu Uzumaki Aug 14 '17 at 11:03
  • @DhanushuPrabhakaran you should filter that inside `router.get('/:id')` – ZeroCho Aug 14 '17 at 16:04
  • I couldn't quite get what you mean by a filter. id is a mongo object id, how do I filter it to have only that? regex? Thanks in advance. – Dhanushu Uzumaki Aug 15 '17 at 04:25
  • @DhanushuPrabhakaran https://stackoverflow.com/questions/11985228/mongodb-node-check-if-objectid-is-valid Check this – ZeroCho Aug 15 '17 at 06:15