2016-11-06 37 views
2
的jsonwebtoken.sign原因

我使用Express和Sequelize能夠基於一個基本的用戶認證upon this tutorial循環引用塊JSON.stringify

當我要簽名令牌用戶我得到一個錯誤,告訴我我試圖以JSON.stringify()作爲無法完成的循環參考。因此會引發錯誤,我無法將令牌分配給用戶。

OR在這使得循環引用OR我只需要找到一個解決方案,以打破循環引用,我想查找數據庫中的我的用戶,當我做錯了什麼。任何人都可以解釋我是哪一個呢?

完整的錯誤是:

TypeError: Converting circular structure to JSON 
    at Object.stringify (native) 
    at toString (/Users/Desktop/express-jwt/node_modules/jws/lib/tostring.js:9:15) 
    at jwsSecuredInput (/Users/Desktop/express-jwt/node_modules/jws/lib/sign-stream.js:12:34) 
    at Object.jwsSign [as sign] (/Users/Desktop/express-jwt/node_modules/jws/lib/sign-stream.js:22:22) 
    at Object.module.exports [as sign] (/Users/Desktop/express-jwt/node_modules/jsonwebtoken/sign.js:144:16) 
    at Model.User.findOne.then.user (/Users/Desktop/express-jwt/server/index.js:69:27) 
    at Model.tryCatcher (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/util.js:16:23) 
    at Promise._settlePromiseFromHandler (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:510:31) 
    at Promise._settlePromise (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:567:18) 
    at Promise._settlePromise0 (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:612:10) 
    at Promise._settlePromises (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/promise.js:691:18) 
    at Async._drainQueue (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/async.js:138:16) 
    at Async._drainQueues (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/async.js:148:10) 
    at Immediate.Async.drainQueues (/Users/Desktop/express-jwt/node_modules/bluebird/js/release/async.js:17:14) 
    at runCallback (timers.js:574:20) 
    at tryOnImmediate (timers.js:554:5) 

我的服務器指標是:

const express = require(`express`); 
const app = express(); 
const bodyParser = require(`body-parser`); 
const morgan = require('morgan'); 

const jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens 
const config = require('./config'); // get our config file 
const db = require(`./models`); 
const User = global.db.User; 

const port = process.env.PORT || 8080; 

db.sequelize.sync().then(() => { 
    console.log(`Express server listening on port ${port}`); 
}); 

app.set('superSecret', config.secret); 

app.use(bodyParser.urlencoded({extended: false})); 
app.use(bodyParser.json()); 

app.use(morgan('dev')); 

app.get('/', (req, res) => { 
    res.send('Hello! The API is at http://localhost:' + port + '/api'); 
}); 

app.listen(port); 
console.log('Magic happens at http://localhost:' + port); 

app.get('/setup', (req, res) => { 

    db.sequelize.sync().then(() => { 
    return User.create({ 
     username: 'Kevin frafster', 
     password: 'password', 
     admin: true 
    }) 
    .then(addedUser => { 
     console.log(addedUser.get({ 
     plain: true 
     })); 
    }) 
    .catch(err => { 
     res.json(err); 
    }); 
    }); 

}); 

// API ROUTES ------------------- 

// get an instance of the router for api routes 
const apiRoutes = express.Router(); 

apiRoutes.post('/authenticate', (req,res) => { 
    User.findOne({ 
    where: {username: req.body.username} 
    }).then(user => { 
    if (!user) { 
     res.json({ success: false, message: 'Authentication failed. User not found.'}); 
    }else{ 
     // console.log(user); 
     if (user.password != req.body.password) { 
     res.json({ success: false, message: 'Authentication failed. Wrong password.' }) 
     }else{ 

     const token = jwt.sign(user, app.get('superSecret'), { 
      expiresIn: 60*60*24 
     }); 

     res.json({ 
      succes: true, 
      message: 'Enjoy your token!', 
      token 
     }); 
     } 
    } 
    }).catch(err => { 
    res.status(500).json(err); 
    }) 
}); 

// TODO: route to authenticate a user (POST http://localhost:8080/api/authenticate) 

// TODO: route middleware to verify a token 

// route to show a random message (GET http://localhost:8080/api/) 
apiRoutes.get('/', (req, res) => { 
    res.json({ message: 'Welcome to the coolest API on earth!' }); 
}); 

// route to return all users (GET http://localhost:8080/api/users) 
apiRoutes.get('/users', (req, res) => { 
    User.findAll({}) 
    .then(users => { 
     res.json(users); 
    }) 
    .catch(err => { 
     res.json(err); 
    }); 
}); 

// apply the routes to our application with the prefix /api 
app.use('/api', apiRoutes); 

回答

3

那麼,答案是完全花生。

1)使新的對象,並指定有效載荷它

const payload = {username: user.username, password: user.password};

2)使用新的對象來分配令牌

const token = jwt.sign(payload, app.get('superSecret'), { 
    expiresIn: 60*60*24 
}); 
+0

我不明白你的意思。哪個用戶對象?你能解釋一下你自己的解決方案嗎?我得到了同樣的問題 –

+1

謝謝。這是拯救我的一天 –