2016-08-02 18 views
1

Passport、MySql、NodeJS、Sequelizeを使用してユーザーサインアップAPIを構築しようとしています。私が直面する唯一の問題は、ユーザーが一度サインアップし、同じ電子メールユーザーで再度サインアップしようとすると、ユーザーオブジェクトの代わりに401 Unauthorized Errorがスローされることです。私が同じデバッグをしようとしたとき、サーバから取得した応答は [オブジェクトSequelizeInstance:users]でした。これらのファイルは以下に記載されています。ありがとうございました。ユーザーサインアップpassport + express + mysql + sequelize

Passport.jsファイル:

var LocalStrategy = require('passport-local').Strategy; 
var mysql = require('mysql'); 
var Model = require('../models/models.js'); 

// expose this function to our app using 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) { 
      connection.query("select * from users where id = " + id, function(err, rows) { 
        done(err, rows[0]); 
      }); 
    }); 


    // ========================================================================= 
    // LOCAL SIGNUP ============================================================ 
    // ========================================================================= 
    // 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-signup', 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) { 
        Model.User.findOne({ 
          where: { 
            email: email 
          } 
        }).then(function(user) { 
          if (user == null) { 
            Model.User.create({ 
              email: email, 
              password: password 
            }).then(function(user) { 
              return done(null, user); 
            }).catch(function(err) { 
              return done(null, err); 
            }); 
          } else { 
            return done(null, false); 
          } 
        }) 

      })); 

}。

申し込みのAPI:

router.post('/signup', passport.authenticate('local-signup'), function(req, res) { 
       // If this function gets called, authentication was successful. 
       // `req.user` contains the authenticated user. 
       console.log(req.user); 
       if(req.user){ 
        res.send({ 
         success: true, 
         response: 'signup successful' 
        }); 
       } else { 
        res.send({ 
         success: false, 
         response: 'Email already in use' 
        }); 
       } 
     }); 

Userモデルは次のとおりです。

//models/users.js 
var Sequelize = require('sequelize') 

var attributes = { 
       id: { 
         type: Sequelize.INTEGER, 
         primaryKey: true, 
         autoIncrement: true 
       }, 
       name: { 
         type: Sequelize.STRING 
       }, 
       email: { 
         type: Sequelize.STRING 
       }, 
       password: { 
         type: Sequelize.STRING 
       }, 
       created_by: { 
         type: Sequelize.INTEGER 
       } 
} 

var options = { 
       // Add the timestamps attributes (updatedAt, createdAt) 
       timestamps: true, 

       // don't delete database entries but set the newly added attribute deletedAt 
       // to the current date (when deletion was done). paranoid will only work if 
       // timestamps are enabled 
       paranoid: true, 

       // don't use camelcase for automatically added attributes but underscore style 
       // so updatedAt will be updated_at 
       underscored: true, 

       // disable the modification of table names; By default, sequelize will automatically 
       // transform all passed model names (first parameter of define) into plural. 
       // if you don't want that, set the following 
       freezeTableName: true, 

       // define the table's name 
       tableName: 'users' 
} 

module.exports.attributes = attributes 
module.exports.options = options 

自動化されたテーブルの作成モデルスクリプトは次のとおりです。

// models/models.js 
var UserMeta = require('./users.js'), 
     connection = require('./index.js') 

var User = connection.define('users', UserMeta.attributes, UserMeta.options) 
     // force: true will drop the table if it already exists 
User.sync({ 
     force: true, 
     match: /_servernew$/ 
}).then(function() { 
     // Table created 
     return User.create(); 
}); 
// you can define relationships here 
module.exports.User = User; 
+0

あなたが達成したいと思うものとやや混乱している...ユーザーが同じ資格情報でサインアップしたい場合、プログラムが正しく動作する - 電子メールアドレスは既に指定されたユーザーと一緒に使用されているため、もう一度サインアップしますか? – deeveeABC

+0

ユーザーが既にサインアップしているのに同じ電子メールで再度サインアップしようとすると、レスポンスは401になり、ユーザーオブジェクトは[object SequelizeInstance:users]というコンソールに記録され、パスポートは正しい応答を返しませんsignup apiが書き込まれたroutes/index.js内のapiルートに対してdone(null、false)を使用するだけです。 –

+0

**警告**:未処理クエリを使用している場合は、[プレースホルダ値](http://docs.sequelizejs.com/en/latest/docs/raw-queries/)を使用するために**必要**があります。エスケープせずに値に文字列連結を使用すると、深刻な[SQLインジェクションのバグ](http://bobby-tables.com/)につながります。 – tadman

答えて

2

だから私は解決策を考え出しました。次のコードを変更する必要があります。

router.post('/signup', function(req, res, next) { 
       passport.authenticate('local-signup', function(err, user, info) { 
         if(user){ 
           req.logIn(user, function(err) { 
             if (err) { 
               return next(err); 
             } else { 
               res.send({ 
                 success: true, 
                 response: 'signup successful' 
               }); 
             } 
           }); 
         } 

         if(!user){ 
           res.send({ 
             success: false, 
             response: 'Authentication Failed' 
           }); 
         } 

         if(err){ 
           res.send({ 
             success: false, 
             response: 'Authentication failed' 
           }) 
         } 
       })(req, res, next); 
     }); 

とpassport.jsコードは次のようにする必要があります。

// ========================================================================= 
     // LOCAL SIGNUP ============================================================ 
     // ========================================================================= 
     // 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-signup', 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) { 

         Model.User.findOne({ 
           where: { 
             email: email 
           } 
         }).then(function(user, err) { 
           console.log('I entered'+user); 
           console.log('I entered'+err); 
           if(err) { 
             console.log(err); 
             return done(null, false); 
           } 

           if(user == null) { 
               Model.User.create({ 
                 email: email, 
                 password: password 
               }).then(function(user) { 
                 return done(null, user); 
               }).catch(function(err) { 
                 return done(null, err); 
               }); 
           } 

           if(user){ 
             return done(null, false); 
           } 

         }) 

       })); 

魅力のように機能します。D。

+0

こんにちは、あなたが私の手助けをすることができますユーザーのサインアップに関する助けが必要ですか? – Kannan

+0

@それは何かっていうかい? –

+0

私はMongooseでそれをやったパスポート仲間とサインアップとログイン操作を実行したいが、この続行はあまりにも混乱しているフィールドは、ユーザー名とパスワードになります。あなたはどこから始めたいのですか? – Kannan

関連する問題