Giter VIP home page Giter VIP logo

easy-node-authentication's Introduction

Easy Node Authentication

Code for the entire scotch.io tutorial series: Complete Guide to Node Authentication

We will be using Passport to authenticate users locally, with Facebook, Twitter, and Google.

Upgraded To Express 4.0

This tutorial has been upgraded to use ExpressJS 4.0. See the commit for specific changes.

Instructions

If you would like to download the code and try it for yourself:

  1. Clone the repo: git clone [email protected]:scotch-io/easy-node-authentication
  2. Install packages: npm install
  3. Change out the database configuration in config/database.js
  4. Change out auth keys in config/auth.js
  5. Launch: node server.js
  6. Visit in your browser at: http://localhost:8080

The Tutorials

easy-node-authentication's People

Contributors

createdd avatar dfearon avatar ggoral avatar jorgefpastor avatar kosssi avatar neverendingqs avatar skotchio avatar travis-robison-prog avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

easy-node-authentication's Issues

Authorization code expires in facebook ,what to do

FacebookTokenError: This authorization code has been used. at Strategy.parseErrorResponse (F:\emproject\educationMedia\emWebApp\server\node_modules\passport-facebook\lib\strategy.js:196:12) at Strategy.OAuth2Strategy._createOAuthError (F:\emproject\educationMedia\emWebApp\server\node_modules\passport-facebook\node_modules\passport-oauth2\lib\strategy.js:367:16) at F:\emproject\educationMedia\emWebApp\server\node_modules\passport-facebook\node_modules\passport-oauth2\lib\strategy.js:166:45 at F:\emproject\educationMedia\emWebApp\server\node_modules\passport-facebook\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:177:18 at passBackControl (F:\emproject\educationMedia\emWebApp\server\node_modules\passport-facebook\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:123:9) at IncomingMessage. (F:\emproject\educationMedia\emWebApp\server\node_modules\passport-facebook\node_modules\passport-oauth2\node_modules\oauth\lib\oauth2.js:143:7) at emitNone (events.js:72:20) at IncomingMessage.emit (events.js:166:7) at endReadableNT (_stream_readable.js:905:12) at doNTCallback2 (node.js:441:9)

node server.js

I get the following error after running node server.js . . . Any ideas why?

Any help would be greatly appreciated!

{ [Error: Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND' }
js-bson: Failed to load c++ bson extension, using pure JS version
The magic happens on port 8080
/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:246
        throw message;      
        ^

MongoError: Authentication failed.
    at Object.toError (/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/utils.js:114:11)
    at /Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1196:31
    at /Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/db.js:1905:9
    at Server.Base._callHandler (/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/base.js:453:41)
    at /Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:488:18
    at MongoReply.parseBody (/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
    at null.<anonymous> (/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/server.js:446:20)
    at emitOne (events.js:77:13)
    at emit (events.js:169:7)
    at null.<anonymous> (/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection_pool.js:207:13)
    at emitTwo (events.js:87:13)
    at emit (events.js:172:7)
    at Socket.<anonymous> (/Users/AbeBook/test_node/easy-node-authentication/node_modules/mongoose/node_modules/mongodb/lib/mongodb/connection/connection.js:440:22)
    at emitOne (events.js:77:13)
    at Socket.emit (events.js:169:7)
    at readableAddChunk (_stream_readable.js:153:18)

Twitter Authentication / Authorization

Thanks for a great tutorial and for sharing the source code.

I cloned the git, and updated things to work with my mongo config, and access my twitter application, and everything works great through the sign-up process.

The only gotcha is that it is requiring the user to approve permissions to access the application every time they sign in.

screen shot 2017-10-08 at 9 04 29 pm

I verified in the node logs that everything looks as expected, including the 302 redirect to profile page after successful login:
screen shot 2017-10-08 at 8 44 33 pm

Twitter documentation states using oauth/authenticate behaves like this: "if the user has already granted the application permission, the redirect will occur without the user having to re-approve the application. To realize this behavior, you must enable the Use Sign in with Twitter setting on your application record."
https://developer.twitter.com/en/docs/basics/authentication/api-reference/authenticate

Chrome inspect agrees that it is hitting oauth/authenticate, but then there appears to be a call to oauth/authorize, which would require the user to re-authenticate access:
screen shot 2017-10-08 at 8 53 27 pm

My understanding is that if your application requires access to DM, then it will force you to use oauth/authorize which means you have to authenticate on each and every login, but my application doesn't have that level of permission.
https://dev.twitter.com/web/sign-in/implementing

screen shot 2017-10-08 at 8 34 43 pm

Is this a problem with the application itself, or perhaps the way passport is accessing the api? Some of the links on the twitter authenticate docs appear to go nowhere leading me to wonder if this is built on an oauth that is being deprecated?

[Security Flaw] Tokens saved to Database in cleartext are vulnerable to attack

Just like we hash and salt our users' passwords, the same treatment should be applied to the social accounts' tokens, as they have the same vulnerabilities as cleartext passwords. A sniffed out token from traffic, including an expired one, can easily give a malicious individual the user's social account's password and id.

@sevilayha I'd be happy to make a PR for this, unless you have better plans for it ๐Ÿ˜€

Congratulations

Friend you are a genius, I congratulate you. I found your profile and wanted to contact you to find out if you have anything that can help me with my instacart autobatch project.

Update to express 4

As this is one of the most popular articles on your website (and extremely helpful) you should seriously consider updating the code base for the passport-local strategy.

Google Authentication Not Working

Google authentication is hitting an error on the callback URL:

Error
   at /Users/Mitchell/Repository/easy-node-authentication/node_modules/passport-google-oauth20/lib/strategy.js:95:21
   at passBackControl (/Users/Mitchell/Repository/easy-node-authentication/node_modules/oauth/lib/oauth2.js:132:9)
   at IncomingMessage.<anonymous> (/Users/Mitchell/Repository/easy-node-authentication/node_modules/oauth/lib/oauth2.js:157:7)
   at emitNone (events.js:110:20)
   at IncomingMessage.emit (events.js:207:7)
   at endReadableNT (_stream_readable.js:1045:12)
   at _combinedTickCallback (internal/process/next_tick.js:138:11)
   at process._tickCallback (internal/process/next_tick.js:180:9)

For clarification, the only changes I made were swapping in my credentials from the Google Developers Console and the URL for my local mongodb server.

Facebook name returns 'undefined undefined'

In passport.js:

// facebook
passport.use(new FacebookStrategy({
    clientID: configAuth.facebookAuth.clientID,
    clientSecret: configAuth.facebookAuth.clientSecret,
    callbackURL: configAuth.facebookAuth.callbackURL,
    passReqToCallback : true
},
function(req, token, refreshToken, profile, done) {
    process.nextTick(function() {
        if (!req.user) {
            User.findOne({ 'facebook.id' : profile.id }, function(err, user) {
                if (err)
                    return done(err);
                if (user) {
                    if (!user.facebook.token) {
                        user.facebook.token = token;
                        user.facebook.name  = profile.name.givenName + ' ' + profile.name.familyName;
                        user.facebook.email = profile.email;

                        user.save(function(err) {
                            if (err)
                                throw err;
                            return done(null, user);
                        });
                    }

                    return done(null, user); // user found, return that user
                } else {
                    var newUser            = new User();

                    newUser.facebook.id    = profile.id;
                    newUser.facebook.token = token;
                    newUser.facebook.name  = profile.name.givenName + ' ' + profile.name.familyName;
                    newUser.facebook.email = profile.email;

                    newUser.save(function(err) {
                        if (err)
                            throw err;
                        return done(null, newUser);
                    });
                }
            });

        } else {
            var user            = req.user;

            user.facebook.id    = profile.id;
            user.facebook.token = token;
            user.facebook.name  = profile.name.givenName + ' ' + profile.name.familyName;
            user.facebook.email = profile.email;

            user.save(function(err) {
                if (err)
                    throw err;
                return done(null, user);
            });
        }
    });
}));

in routes.js:

app.get('/auth/facebook', passport.authenticate('facebook', { scope : 'email' }));

app.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect : '/profile',
failureRedirect : '/'
}));

I've spent a couple hours trying to figure out why 'newUser.facebook.name = profile.name.givenName + ' ' + profile.name.familyName;' keeps returning 'undefined undefined' - any ideas?

Reason for /connect/... routes

I am sorry, I really do not understand the reason for the /connect/.../ routes in this example?

/auth/google and /connect/google seem to be identical? And the intelligence of linking the accounts are all done in the Strategy..

I am sorry if I am missing what could be an obvious point.

The only thing I can think of is if you wanted /connect/google/ and /auth/google to render different pages and this example just hasn't gone that complex?
If that is the case then it wasn't obvious to me that that was the case.

  • Colin

Tokens problem

Hi I am trying to implement your solution on my project. I am using https://github.com/DaftMonk/generator-angular-fullstack as a base it is a little bit different because it is using JWT tokens instead of sessions. I am curious what I would need to change to make it work with JWT tokens especially when you are connected using local method and then you would like to add connect to facebook with local account. I guess you would need to pass token trough facebook somehow ?

Thanks

Port & Facebook

I changed the port in server.js and I'm still sending the old port number to facebook and I'm getting an error.

err BSON

{ [Error: Cannot find module '../build/Release/bson'] code: 'MODULE_NOT_FOUND' }
js-bson: Failed to load c++ bson extension, using pure JS version
The magic happens on port 8080
events.js:141

local authentication not working!

Error: Unknown authentication strategy "local-login" this error comes on login and when I replace "local-login" with "local" the passport.authenticate funtion always returns false and I am unable to log in

'/connect/*/callback' URLs aren't visited after authorize

/connect/* URLs are using passport.authorize('*'), whose callback URLs are set to http://localhost:8080/auth/*/callback.
My temporary fix is making another set of passport.authorize('*-connect'), whose callback URLs are set to http://localhost:8080/connect/*/callback.

Connection to MongoDB drops

Hi there,

Fantastic repo! I was bummed that the app connects to the database, but the connection drops whenever I try to do local signup. I noticed that I'm not the only one who has had this issue before (based on your tutorial comments). I've verified that the connection is established, but I can't figure out why it hangs and drops. Any ideas?

image

Thanks!

Jason

Problems Linking a Local Account & No cleanup when linking

I created a local account with email [email protected] and then i created a google account for [email protected] so now i have 2 accounts in the user table. then i login to the google account and try to link the local account and it doesn't work... for whatever reason it fails.

but if i do the reverse and login to the local account and link the google account, then it works fine.

also i noticed that i still have 2 account after linking the accounts... shouldn't there be a cleanup? or never even create the second account if we have a match in the emails?

Email Id is undefined in Facebook login

I am trying to get users email id, but it is not coming in the response.
I'm new to node js.
I don't want to store user details in mongo db. How to remove mongodb dependencies.

Adding JSON Web Token support

Hey, hopefully you see this post as I know it's been a while since there was any activity on this repo. I've gone through and completed your other tutorial on JWTs and was actually looking for your advice on how to implement it into this repo. So far, I've converted this repo to a fully Angular app that's using all the up-to-date dependencies etc. and am ready to implement the JWT support.

On the client, these are the changes I think I'd need to make:

  • Transfer all the auth related HTTP requests into an Auth Service of some sort.
  • When doing $http.post('/login'), I would receive a token on success and add it to $rootScope (as well as the user's data) so that it can be used throughout the app.
  • Edit the httpInterceptor to put the token in the headers for the request so that it can be checked on the server.
    I think these are the only changes I would need to make, so let me know if you think otherwise. I think this approach would be exactly the same for the social logins too, and when doing all the connect routes, the client would just send the token when making a HTTP call of some sort.

On the server, things would get a little more complicated, so I'd like your advice on whether this would be a good approach:

  • Add in jsonwebtoken
  • Create a function to take in a user and creates a token which encodes the user's _id too.
  • With the createToken function, all login or signup requests would simply create a token if the login/signup was successful and return the token/user data. I believe this is simple, but maybe I'm missing something.
  • The only other thing that would be needed is an isAuthenticated function to authenticate the routes such as connect or any update requests. So here I would check req.headers and req.headers.authorization for a token and use jwt.decode to get the data from it. If it passes all the basic checks such as expired or non-existent user, then we'd call next(); and move into the route that has successfully been authenticated.

I'm thinking that this is all I need to do, but as I said I can't help but feel I'm missing something, especially on the client side of things. Your input would be well appreciated!

Cannot read property '0' of undefined

After signing in using facebook, this happens:

C:\Users\callum.PIXELPIN\Documents\facebook\config\passport.js:106
                    newUser.facebook.email = profile.emails[0].value; // facebook can return multiple emails so we'll take
 the first
                                                           ^

TypeError: Cannot read property '0' of undefined
    at Promise.<anonymous> (C:\Users\callum.PIXELPIN\Documents\facebook\config\passport.js:106:60)
    at Promise.<anonymous> (C:\Users\callum.PIXELPIN\Documents\facebook\node_modules\mpromise\lib\promise.js:177:8)
    at emitOne (events.js:96:13)
    at Promise.emit (events.js:188:7)
    at Promise.emit (C:\Users\callum.PIXELPIN\Documents\facebook\node_modules\mpromise\lib\promise.js:84:38)
    at Promise.fulfill (C:\Users\callum.PIXELPIN\Documents\facebook\node_modules\mpromise\lib\promise.js:97:20)
    at Immediate.cb (C:\Users\callum.PIXELPIN\Documents\facebook\node_modules\mongoose\lib\query.js:1153:30)
    at Immediate.<anonymous> (C:\Users\callum.PIXELPIN\Documents\facebook\node_modules\mquery\lib\utils.js:137:16)
    at runCallback (timers.js:574:20)
    at tryOnImmediate (timers.js:554:5)
    at processImmediate [as _immediateCallback] (timers.js:533:5)

Race condition issue?

Hi there โ€“ awesome project!

I'm wondering if there's a small bug around this code.

When the if statement matches, an attempt is made to update the user before passing it along to done. However, the call to done immediately after the if statement will likely always resolve before the update to the user completes.

This probably wouldn't affect some applications, because the update call is getting instantiated. But the middleware is likely moving onto to the next middleware a little earlier than expected.

Another consequence of this is that done will get called twice, which I'm pretty sure goes against the contract of how done is intended to be used.

I'm thinking it should instead be:

if (!user.facebook.token) {
  user.facebook.token = token;
  user.facebook.name  = profile.name.givenName + ' ' + profile.name.familyName;
  user.facebook.email = profile.emails[0].value;

  user.save(function(err) {
    if (err)
      throw err;
    return done(null, user);
  });
} else {
  return done(null, user); // user found, return that user
}

This issue likely affects the other services' code, too. What do you think?

Why app.get('/profile' ? Why /profile page at all?

I wonder why do you make so inconvenient design?
Do FB, Amazon, Ebay, any modern sites have some special dedicated pages to get you to your profile?
If you were loged in, you just follow facebook.com (not facebook.com/profile or smth !!) and simply get to your members restricted area.
Why do you make up some useless /profile routes?

Express 4?

Hi! Great tutorial, would this work with Express 4? Thanks

MongoError: connection 0 to localhost:8081 closed at Function.MongoError.create

Hello bro, When I run "nodemon server.js" then show this error. I'm tried for the error

# 1. server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var passport = require('passport');
var ejs = require('ejs');
var session = require('express-session');
var flash = require('connect-flash');
var cookieParser = require('cookie-parser');
const mongoose = require('mongoose');
var dbUrl = require('./config/db.js').url;

var option = {
socketTimeoutMS: 30000,
keepAlive: true,
reconnectTries: 30000
};
// Connect to mongoose
mongoose.connect(dbUrl);
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function () {
console.log('Connected');
});

app.use(flash());
app.use(session({
secret: 'meanlocalauth'
}));
app.use(bodyParser.json);
app.use(bodyParser.urlencoded({
extended: false
}))
app.use(passport.initialize());
app.use(passport.session());

require('./router/routes.js')(app);
// require('./passport.js')(app, passport);

app.use(morgan('dev'));
var PORT = process.env.PORT || 8081;
app.listen(PORT, function(){
console.log('Listening on port '+ PORT);
});

#2. db.js
module.exports = {
'url': 'mongodb://localhost:8081/loginapp'
}

# 3.package.json
{
"dependencies": {
"bcrypt-nodejs": "0.0.3",
"body-parser": "^1.18.3",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.3",
"ejs": "^2.6.1",
"express": "^4.16.3",
"express-session": "^1.15.6",
"mongodb": "^3.0.10",
"mongoose": "^4.10.8",
"morgan": "^1.9.0",
"passport": "^0.4.0",
"passport-local": "^1.0.0"
},
"scripts": {
"start": "node server.js"
},
"name": "loginapp",
"version": "1.0.0",
"main": "server.js",
"devDependencies": {},
"author": "Masum",
"license": "MIT",
"description": ""
}

connection error: { MongoError: connection 0 to localhost:8081 closed
at Function.MongoError.create (/Users/ms/loginApp/node_modules/mongoose/node_modules/mongodb-core/lib/error.js:29:11)
at Socket. (/Users/ms/loginApp/node_modules/mongoose/node_modules/mongodb-core/lib/connection/connection.js:202:22)
at Object.onceWrapper (events.js:315:30)
at emitOne (events.js:116:13)
at Socket.emit (events.js:211:7)
at TCP._handle.close [as _onclose] (net.js:554:12)
name: 'MongoError',
message: 'connection 0 to localhost:8081 closed' }

Error: req.flash() requires sessions

I am getting the below error when open "login" link

Error: req.flash() requires sessions
at Error (native)
at IncomingMessage._flash [as flash](c:UsersxxxDesktopMEAN Stackshoppingnode_modulesconnect-flashlibflash.js:60:41)
at Object.handle (c:\Users\xxx\Desktop\MEAN Stack\shopping\app\routes.js:14:48)
at next_layer (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\route.js:103:13)
at Route.dispatch (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\route.js:107:5)
at c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:195:24
at Function.proto.process_params (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:251:12)
at next (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:189:19)
at next (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:166:38)
at Layer.handle (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\connect-flash\lib\flash.js:21:5)
at trim_prefix (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:226:17)
at c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:198:9
at Function.proto.process_params (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:251:12)
at Context.next (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\express\lib\router\index.js:189:19)
at Context.actions.pass (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\passport\lib\passport\context\http\actions.js:77:8)
at SessionStrategy.authenticate (c:\Users\xxx\Desktop\MEAN Stack\shopping\node_modules\passport\lib\passport\strategies\session.js:67:10)

Kindly do the needful ASAP

Thanks in Advance

passReqToCallback in passport 0.2.0

hello there. thanks for this tutorial. its really helping me out. the one snag is that there doesn't seem to be a method in passport 0.2.0 for binding the request to the callback. do you know how i could use this with 0.2.0? would be great to know! thanks.

broken without error messages.

We recently upgraded to Fedora 27 OS, updated all packages, .. and the login - registration mechanism stopped working. Investigating the issue, but there are no error messages. It just drops an error 500 in the browser after a longer period of time ...

if anyone has any ideas how to troubleshoot this, please write here ...

Critical Security Flaw - Mongoose Model inside Webtoken

Hi,

I noticed that you do have your full mongoose model inside the generated json webtoken. This is a huge security flaw, as a json webtoken is only signed but not encrypted, meaning that everyone who can retrieve a token from a user ( e.g sniffing ) is able to obtain the users cleartext password, even from expired tokens.

https://github.com/scotch-io/node-token-authentication/blob/master/server.js#L81

Please consider fixing this asap

~Mydayyy

Edit: I got asked to go a little more indepth about the underlying security issue here.

So basically, take a look at the line https://github.com/scotch-io/node-token-authentication/blob/master/server.js#L81

You see that the token gets created with jwt.sign(user, app.get('sup erSecret'), { expiresIn: 86400 // expires in 24 hours }). First argument, the user, is passed by mongodb as a response to the findOne query. This object contains all model data. Now, that user object is put into the JWT as a payload.

A JsonWebToken is signed but not encrypted, that means while we can verify that the content has not changed, it is still public for everyone. If you now receive a token by the API it contains all user information, including the cleartext password.

See the following webtoken for example ( which is returned by this API ):

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyIkX18iOnsic3RyaWN0TW9kZSI6dHJ1ZSwic2VsZWN0ZWQiOnt9LCJnZXR0ZXJzIjp7fSwiX2lkIjoiNTljZTRhNTUyZDQwODQ2YzBiOTM4MDg1Iiwid2FzUG9wdWxhdGVkIjpmYWxzZSwiYWN0aXZlUGF0aHMiOnsicGF0aHMiOnsiX192IjoiaW5pdCIsImFkbWluIjoiaW5pdCIsInBhc3N3b3JkIjoiaW5pdCIsIm5hbWUiOiJpbml0IiwiX2lkIjoiaW5pdCJ9LCJzdGF0ZXMiOnsiaWdub3JlIjp7fSwiZGVmYXVsdCI6e30sImluaXQiOnsiX192Ijp0cnVlLCJhZG1pbiI6dHJ1ZSwicGFzc3dvcmQiOnRydWUsIm5hbWUiOnRydWUsIl9pZCI6dHJ1ZX0sIm1vZGlmeSI6e30sInJlcXVpcmUiOnt9fSwic3RhdGVOYW1lcyI6WyJyZXF1aXJlIiwibW9kaWZ5IiwiaW5pdCIsImRlZmF1bHQiLCJpZ25vcmUiXX0sInBhdGhzVG9TY29wZXMiOnt9LCJlbWl0dGVyIjp7ImRvbWFpbiI6bnVsbCwiX2V2ZW50cyI6e30sIl9ldmVudHNDb3VudCI6MCwiX21heExpc3RlbmVycyI6MH19LCJpc05ldyI6ZmFsc2UsIl9kb2MiOnsiX192IjowLCJhZG1pbiI6dHJ1ZSwicGFzc3dvcmQiOiJwYXNzd29yZCIsIm5hbWUiOiJOaWNrIENlcm1pbmFyYSIsIl9pZCI6IjU5Y2U0YTU1MmQ0MDg0NmMwYjkzODA4NSJ9LCIkaW5pdCI6dHJ1ZSwiaWF0IjoxNTA2NjkxNzIyLCJleHAiOjE1MDY3NzgxMjJ9.WFZU_FwYzglN0vagVvBn4NYEaOS2tmKbUjrDUyhp8fQ

Go to https://jwt.io/ and select Debugger in the navigation panel. Now paste that token there. It will display the content which is the following:

  "$__": {
    "strictMode": true,
    "selected": {},
    "getters": {},
    "_id": "59ce4a552d40846c0b938085",
    "wasPopulated": false,
    "activePaths": {
      "paths": {
        "__v": "init",
        "admin": "init",
        "password": "init",
        "name": "init",
        "_id": "init"
      },
      "states": {
        "ignore": {},
        "default": {},
        "init": {
          "__v": true,
          "admin": true,
          "password": true,
          "name": true,
          "_id": true
        },
        "modify": {},
        "require": {}
      },
      "stateNames": [
        "require",
        "modify",
        "init",
        "default",
        "ignore"
      ]
    },                 
    "pathsToScopes": {},
    "emitter": {
      "domain": null,
      "_events": {},
      "_eventsCount": 0,
      "_maxListeners": 0
    }
  },
  "isNew": false,
  "_doc": {
    "__v": 0,{
  "$__": {
    "strictMode": true,
    "selected": {},
    "getters": {},
    "_id": "59ce4a552d40846c0b938085",
    "wasPopulated": false,
    "activePaths": {
      "paths": {
        "__v": "init",
        "admin": "init",
        "password": "init",
        "name": "init",
        "_id": "init"
      },
      "states": {
        "ignore": {},
        "default": {},
        "init": {
          "__v": true,
          "admin": true,
          "password": true,
          "name": true,
          "_id": true
        },
        "modify": {},
        "require": {}
      },
      "stateNames": [
        "require",
        "modify",
        "init",
        "default",
        "ignore"
      ]
    },
    "pathsToScopes": {},
    "emitter": {
      "domain": null,
      "_events": {},
      "_eventsCount": 0,
      "_maxListeners": 0
    }
  },
  "isNew": false,
  "_doc": {
    "__v": 0,
    "admin": true,
    "password": "password",
    "name": "Nick Cerminara",
    "_id": "59ce4a552d40846c0b938085"
  },
  "$init": true,
  "iat": 1506691722,
  "exp": 1506778122
}
    "admin": true,
    "password": "password",
    "name": "Nick Cerminara",
    "_id": "59ce4a552d40846c0b938085"
  },
  "$init": true,
  "iat": 1506691722,
  "exp": 1506778122
}

This means that everyone who can receive that token has all information about the user. For example, if we would insert an email field for the user it will also show up there. This is even true for expired tokens. So every token the user ever created has all information about him inside, including the cleartext password.

This is obviously a huge security flaw.
A possible fix would be to only include selected attributes inside the payload of the token, not the entire model.

Further edit: Accidentally closed this issue. Lesson learned. Look where you click! Sorry! #

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.