我正在使用passportJS创建一个快速应用程序,我正在尝试使用JSON Web令牌验证我的api:
该应用程序同时具有本地用户和Facebook用户,并以mongoose架构一起定义:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var UserSchema = mongoose.Schema({
name: {
type: String
},
password: {
type: String
},
local: {
type: String,
enum: [
'0',
'1'
]
},
fbId : String,
fbToken : String,
fbEmail : String,
fbName : String
});
UserSchema.pre('save', function(callback) {
var user = this;
if (user.local == '1') {
if (!user.isModified('password'))
return callback();
bcrypt.genSalt(5, function (err, salt) {
if (err)
return callback(err);
bcrypt.hash(user.password, salt, null, function (err, hash) {
if (err)
return callback(err);
user.password = hash;
callback();
});
});
}
else {
callback();
}
});
UserSchema.methods.verifyPassword = function(password, cb) {
bcrypt.compare(password, this.password, function(err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
module.exports = mongoose.model('User', UserSchema);
主app.js文件包含以下代码,我使用config / passport.js文件(紧随其后)配置护照
var express = require('express');
var app = express();
var passport = require('passport');
var jwt = require('jsonwebtoken');
app.use(passport.initialize());
require('./config/passport')(passport);
app.get('/auth/facebook', passport.authenticate('facebook', {scope:['email']}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', {session: false, failureRedirect: '/', successRedirect: '/user'})
);
app.post('/authenticate', function(req, res) {
User.findOne({
name: req.body.name
}, function(err, user) {
if (err) throw err;
if (!user) {
res.send({success: false, msg: 'Authentication failed. User not found.'});
} else {
user.verifyPassword(req.body.password, function (err, isMatch) {
if (isMatch && !err) {
var token = jwt.sign(user, "mysecret");
res.json({success: true, token: 'JWT ' + token});
} else {
res.send({success: false, msg: 'Authentication failed. Wrong password.'});
}
});
}
});
});
app.all('/api/*',
passport.authenticate('jwt', {session: false}),
function (req, res, next) {
next();
});
这是config / passport.js文件,我在其中定义了JwtStrategy和FacebookStrategy。此外,这是我为Facebook用户发出令牌的地方:
var FacebookStrategy = require('passport-facebook').Strategy;
var User = require('../models/user');
var jwt = require('jsonwebtoken');
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
module.exports = function(passport) {
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeader();
opts.secretOrKey = "mysecret";
passport.use(new JwtStrategy(opts, function (jwt_payload, done) {
console.log("I'm here!");
User.findOne({id: jwt_payload.id}, function (err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
passport.use(new FacebookStrategy(
{
clientID : '...',
clientSecret : '...',
callbackURL : 'http://localhost:3000/auth/facebook/callback',
profileFields : ['id', 'emails', 'name']
},
function(accessToken, refreshToken, profile, done) {
process.nextTick(function() {
User.findOne({ 'fbId' : profile.id }, function(err, user) {
if (err)
return done(err);
if (user) {
var token = jwt.sign(user, "mysecret");
console.log('JWT ' + token); //I'm doing this in orer to copy the token and paste it on Postman
return done(null, ({success: true, token: 'JWT ' + token}));
} else {
var newUser = new User();
newUser.local = '0';
newUser.fbId = profile.id;
newUser.fbToken = accessToken;
newUser.fbName = profile.name.givenName + " " + profile.name.familyName;
newUser.fbEmail = profile.emails[0].value;
newUser.save(function(err) {
if (err)
throw err;
var token = jwt.sign(newUser, "mysecret");
return done(null, {success: true, token: 'JWT ' + token});
});
}
});
});
}
));
};
本地用户的身份验证和授权工作正常,我已经使用Postman进行了测试:
但是当我用我为facebook用户创建的令牌替换本地用户的令牌时,我没有获得授权:
另外,当我尝试使用facebook用户的令牌访问API时,我甚至没有得到“我在这里!!”控制台日志消息(我已在JwtStrategy中定义),而在本地用户的情况下,我这样做。
任何想法我做错了什么?
提前多多感谢!
编辑:我发现如果我代替用户签署以下对象:
var toSign = user.fbId + user.fbName + user.fbEmail
即。没有fbToken,我获得了授权。
为什么会这样?