【问题标题】:Res.json is not a function (passport.js)Res.json 不是函数(passport.js)
【发布时间】:2019-01-11 09:38:07
【问题描述】:

今天我遇到了一个全新的问题! 首先,我有两个重要文件:

passport.js 本地注册部分

passport.use('local-signup', new LocalStrategy({
        usernameField: 'email',
        passwordField: 'password',
        passReqToCallback: true // allows us to pass back the entire request to the callback
    },

    function(req, res) {
        var password = req.body.password;
        var email = req.body.email;

        var generateHash = function(password) {
            return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
        };

        User.find({
            where: {
                email: email
            }
        }).then(function(user) {
            if (user) {
                return res.json('That email is already taken');

            } else {
                var userPassword = generateHash(password);
                var data = {
                    username: req.body.username,
                    name: req.body.name,
                    firstname: req.body.firstname,
                    email: req.body.email,
                    location: req.body.location,
                    type: req.body.type,
                    password: userPassword
                };

                db.users.create({
                    username: data.username,
                    name: data.name,
                    firstname: data.firstname,
                    email: data.email,
                    location: data.location,
                    type: data.type,
                    password: data.password
                }).then(newUser => {
                    return res.json(newUser)
                });
            }
        });
    }
));

我正在做一个身份验证部分。首先,我想创建一个帐户并为其使用护照:注册。

我还使用 Sequelize 来管理我的数据模型。 但是当我用 POST 请求调用这个 localStrategy 时(我的身体在邮递员中一切正常)我有这个错误:

Unhandled reject TypeError: res.json is not a function就行了 返回 res.json(newUser)

有人可以帮帮我吗? 请注意,由于 passReqToCallback,done() 不起作用(但我需要这个来获取我的密码和电子邮件)

【问题讨论】:

  • 你在用 expressjs 吗?
  • 是的,对不起,我忘了告诉

标签: node.js sequelize.js passport.js


【解决方案1】:

您可能会有些困惑,但护照没有实现注册方法。它只是授权库。因此,您必须自己处理该用例。

首先,创建负责注册和检查的路由:

app.post('/signup', (req, res) => {

    User.findOne({ $or: [{'local.email': req.body.email},{'local.username': req.body.username}]}, function(err, user){
        if(err){
            return res.send(err);
        }
        if(user){
            if(user.local.email == req.body.email){
                return res.send("This email is already taken.")
            }
            return res.send("This username is already taken.")

        }
        else{
            var userData = new User();

            userData.local.name = req.body.name;
            userData.local.email = req.body.email;
            userData.local.username = req.body.username;
            userData.local.password = req.body.password;

            userData.save()
                .then(item => {
                    res.send("item saved to database")
                    // `req.user` contains the authenticated user.
                    //res.redirect('/profile/' + req.body.username);
                })
                .catch(err => {
                    console.log(err);
                    res.status(400).send("unable to save to database");
                })

                }
            })

})  

上面的例子是基于 express 框架的,但是你可以毫无问题地适应你自己的情况。

下一步是包括护照本地策略。 // 加载我们需要的所有东西 var LocalStrategy = require('passport-local').Strategy;

//加载用户模型 var User = require('../models/user');

// 使用 module.exports 将此函数暴露给我们的应用程序 module.exports = function(passport) {

// =========================================================================
// passport session setup ==================================================
// =========================================================================
// required for persistent login sessions
// passport needs ability to serialize and unserialize users out of session

// used to serialize the user for the session
passport.serializeUser(function(user, done) {
    done(null, user.id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
        done(err, user);
    });
});


// =========================================================================
// LOCAL LOGIN =============================================================
// =========================================================================
// we are using named strategies since we have one for login and one for signup
// by default, if there was no name, it would just be called 'local'

passport.use('local-login', new LocalStrategy({
    // by default, local strategy uses username and password, we will override with email
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) { // callback with email and password from our form

    // find a user whose email is the same as the forms email
    // we are checking to see if the user trying to login already exists
    User.findOne({ 'local.email' :  email }, function(err, user) {
        // if there are any errors, return the error before anything else
        if (err)
            return done(err);

        // if no user is found, return the message
        if (!user)
            return done(null, false, {message: 'User not found.'}); // req.flash is the way to set flashdata using connect-flash
        // if the user is found but the password is wrong
        if (!user.validPassword(password))
            return done(null, false, {message: 'Incorrect password.'}); // create the loginMessage and save it to session as flashdata

        // all is well, return successful user
        return done(null, user);
    });

}));

};

我们现在只有登录任务。很简单。

app.post('/login', function(req, res, next) {
    passport.authenticate('local-login', function(err, user, info) {
      if (err) { return next(err); }
      if (!user) { return res.send(info.message); }
      req.logIn(user, function(err) {
        if (err) { return next(err); }
        return res.send(user.local.username);
      });
    })(req, res, next);
  });

【讨论】:

  • 嗨!谢谢你的帮助 !我使用了您的解决方案,但是当我调用注册 POST 时,我的功能并没有结束。它只显示:执行(默认):SELECT "user_id", "username", "name", "firstname", "email", "type", "location", "password", "createdAt", "updatedAt" FROM “用户”作为“用户”限制 1;
  • 登录相同*
  • 请分享您的注册 api
  • 上面的链接是我的模型,你可以在其中看到模式,,,对于用户注册,我在本地对象上注册数据如果你不想要,那么你从你的代码中删除 user.local,只是像这样使用 user.name,,,
  • github.com/mdashikar/mevn-user-reg-module/tree/master/server 你可以看到我的代码本地用户注册设置
【解决方案2】:

Passport localStrategy 在回调中没有 res。它的请求,用户名,密码和完成。这是一个例子。

passport.use('local-signup', new LocalStrategy({
    usernameField : 'email',
    passwordField : 'password',
    passReqToCallback : true
},
function(req, email, password, done) {
    // request object is now first argument
    // ...
  }
));

【讨论】:

    【解决方案3】:

    你在 req.json 中传递了一个字符串。你需要使用 req.send 作为字符串。 示例:

    替换这一行:

     return res.json('That email is already taken');
    

    return res.send('That email is already taken');
    

    如果您想发送 JSON,请使用这个。

    return res.json({msg:'That email is already taken'});
    

    或者使用这个条件

    if (req.xhr) { return res.json({msg:'That email is already taken'}) }
    

    【讨论】:

    • 没关系。 res.json 也接受字符串。您也可以在示例应用程序中检查它。它会打印一对双引号。
    • 我不认为 res.json 只接受字符串。请仔细阅读此文档。 expressjs.com/en/guide/routing.html
    • 是的。 :)expressjs.com/en/4x/api.html#res.jsonThe parameter can be any JSON type, including object, array, string, Boolean, or number, and you can also use it to convert other values to JSON, such as null, and undefined (although these are technically not valid JSON).
    猜你喜欢
    • 2018-03-19
    • 2018-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多