вход в facebook с помощью node.js

У меня есть приложение. Когда я пытаюсь войти в систему с помощью facebook, возникает ошибка.

Ошибка {"error": "E_VALIDATION", "status": 400, "summary": "1 атрибут недействителен", "model": "User", "invalidAttributes": {"email": [{"rule": "string", "message": "_ 1_ должно быть строкой (вместо \" null \ ", который является объектом)"}, {"rule": "email", "message": "\" email \ " Ошибка правила проверки для ввода: null "}, {" rule ":" required "," message ":" \ "required \" Правило проверки не выполнено для ввода: null "}]}} [TypeError: невозможно прочитать свойство 'nickname' из неопределенных]

Моя пользовательская модель выглядит так:

/**
* User
*
* @module      :: Model
* @description :: A short summary of how this model works and what it          represents.
* @docs     :: http://sailsjs.org/#!documentation/models
*/

var Q=require('q')
module.exports = {

/* e.g.
nickname: 'string'
*/
attributes  : {
  provider: {
      type:'string',
      required:true
  },
  uid: {
      type:'integer',
      required:true
  },
  name: 'string',
  email: {
      type:'string',
      email:true,
      required:true
  },
  firstname: {
      type:'string'
  },
  lastname: {
      type:'string'
  },
  admin:{
      type:'boolean',
      defaultsTo:false
  },
  lastLoginAt:{
      type:'date'
  },
  firstLoggedInAt:{
      type:'date'
  },
  profileUpdated:{
      type:'boolean',
      defaultsTo:false
  },
  phoneNumber:{
      type:'integer'
  },
  dealClaims:{
      collection:'dealClaim',
      via:'user'
  },
  parties:{
      collection:'party',
      via:'user'
  },
  origin:{
      type:'string',
      defaultsTo:'web'
  },
  city:{
      type:'string',
      defaultsTo:'Bangalore'
  },
  currentCity:function(){
     return this.city||'Bangalore'
  },
  claimDealWith:function(dealId){
      var deferredClaim= Q.defer()
      sails.log.info('Im here',this.email,dealId,this.phoneNumber);
      Dealclaim.create({email:this.email,phoneNumber:this.phoneNumber,deal:dealId,user:this.id},function(err,dealClaim){

          if(err||!dealClaim){
               deferredClaim.reject(err)
               return
           }
          sails.log.info('dealClaim',dealClaim)
          Deal.findOne(dealClaim.deal)
              .populate('listing')
              .then(function(deal){
                  deferredClaim.resolve({deal:deal,dealClaim:dealClaim})
              })
              .fail(function(err){
                  deferredClaim.reject(err)
              })

      })
      return deferredClaim.promise
  },
  login:function(){
      var deferred= Q.defer()
      var currentDate=new Date()
      var updateConditions={lastLoginAt:currentDate}
      if(!this.firstLoggedInAt){
          updateConditions.firstLoggedInAt=currentDate
      }
      User.update(this.id,updateConditions,function (err){
          sails.log.info('last login date for user:',this.id)
          if(err){
              deferred.reject(err)
          }
          deferred.resolve()
      })
      return deferred.promise
  },
  completeProfile:function(data){
      var deferred= Q.defer()
      this.phoneNumber=(data.phoneNumber||this.phoneNumber);
      this.email=(data.email||this.email)
      this.city=(data.city||this.city)
      sails.log.info('city==>',this.city)
      //sails.log.info('email',this.email,User.validateEmail(this.email),(this.email==='[email protected]'||(!this.email)||User.validateEmail(this.email)),'phone',this.phoneNumber)
      if(this.email==='[email protected]'||(!this.email)||!User.validateEmail(this.email)){
          deferred.reject({ValidationError:{invalidEmail:'Invalid Email'}})
          return deferred.promise
      }
      if((!this.phoneNumber)||isNaN(this.phoneNumber)){
          deferred.reject({ValidationError:{invalidPhoneNumber:'Invalid Phone number'}})
          return deferred.promise
      }
      this.profileUpdated=true
      this.save(function(err){
          if(err){
              sails.log.error(err.stack)
              deferred.reject(err)
          }else{
              deferred.resolve()
          }
      })
      return deferred.promise
  },
  providedEmail:function(){
       return this.email==='[email protected]'?undefined:this.email;
  },
  planMyParty:function(party){
      var deferred= Q.defer()
      //i should us
      this.parties.add({numberOfPeople:party.numberOfPeople,locationOrPlace:party.locationOrPlace})
      this.save(function(err){
          if(err){
            deferred.reject(err)
            return
          }
          deferred.resolve(party)
      })
      return deferred.promise
  }


  },
  validateEmail:function(email){
  var regex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
  return regex.test(email)
  },
      beforeCreate:function makeAdmin(values,next){
  sails.log.warn("BOOYA IM HERE!!")

  var deferred=Q.defer()
  Admin.findOneByEmail(values.email).then(function foundAdmin(err,admin){
          if(err || !admin){
              sails.log.warn("User with email"+values.email+" tried to gain access to restricted urls")
              //return next({err:["only admins allowed"]},null)
              values.admin=false
          } else{
              values.admin=true
          }
        deferred.resolve()
      })
  deferred.promise.fin(function(){
      next()
  })
  return deferred.promise

  },
    createSession:function(profile){
    var deferred= Q.defer();
    if(!profile){
        deferred.reject(new Error("Unable to login to the server"))
        return deferred.promise
    }
    User.findOne({
            or: [
                {uid: parseInt(profile.id)},
                {uid: profile.id}
            ]
        }
    ).exec(function (err, user) {
            if (user) {
                //sails.log.info('User Exists')
                user.login()
                    .then(function(){
                        deferred.resolve(user);
                    }).fail(function(){
                        deferred.reject();
                    })
            } else {

                var data = {
                    provider: profile.provider,
                    uid: profile.id,
                    name: profile.displayName
                };

                if (profile.emails && profile.emails[0] && profile.emails[0].value) {
                    data.email = profile.emails[0].value;
                }
                if (profile.name && profile.name.givenName) {
                    data.firstname = profile.name.givenName;
                }
                if (profile.name && profile.name.familyName) {
                    data.lastname = profile.name.familyName;
                }
                if(!profile.email){
                    data.email='[email protected]'
                }
                data.origin=profile.origin
                User.create(data).exec(function (err, user) {
                    if(err||!user){
                        sails.log.error('Unable to create user',err.stack)

                        deferred.reject(err)
                    }
                    if(user){
                        user.login()
                            .then(function(){
                                deferred.resolve(user);
                            }).fail(function(){
                                deferred.reject();
                            })
                    }
                });
            }
        });
    return deferred.promise;
},
findForClaim:function(id){
    var deferred= Q.defer();
    User.findOne(id)
        .exec(function(err,user){
            if(err){
               deferred.reject(err)
                return
            }
            if((!user.email)||(!user.phoneNumber)){
                deferred.reject('No email or phoneNumber')
                return
            }
            sails.log.info('Here-->',user.email)
            deferred.resolve(user)
        })
    return deferred.promise
}




};

Код AuthController выглядит так:

facebook: function (req, res) {
    passport.authenticate('facebook', { failureRedirect: '/login', scope: ['public_profile','email'] },
        function (err, user) {
            req.logIn(user, function (err) {
                if (err) {
                    console.log(err);
                    res.view('500');
                    return;
                }

                res.redirect('/');
                return;
            });
        })(req, res);
},

Конфигурационный файл facebook выглядит так:

facebook:{
        clientID: "ID",
        clientSecret: "SECRET",
        callbackURL: "http://localhost:1337/auth/facebook/callback"
    }

Страница просмотра выглядит так:

<div class="main">
<% if(flash && flash.err) { %>
<ul class="alert alert-danger">
    <% Object.keys(flash.err).forEach(function(index){%>
    <% if (flash.err[index].message != undefined) {%>
    <li><%=JSON.stringify(flash.err[index].message)%></li>
    <% } %>
    <% })%>
    <li></li>
</ul>
<% }%>
<h1 id="main-title">Please sign in</h1>
<a href="/auth/facebook/" class="btn">with Facebook</a>
<a href="/logout" class="btn">Logout</a>

When i click on "With facebook" button m getting logs like this:

info: Device type { type: 'desktop' }
verbose: Running res.view([object Object])...
verbose: Using layout:  /home/testgulp/Desktop/funtestgulp/views/layoutBW
verbose: Rendering view :: site/index (located @ /home/testgulp/Desktop/funtestgulp/views/site/index)
info: inside flash policy
verbose: Running res.view()...
verbose: Using layout:  /home/testgulp/Desktop/funtestgulp/views/layoutBW
verbose: Rendering view :: auth/index (located @  /home/testgulp/Desktop/funtestgulp/views/auth/index)
info: inside flash policy
info: inside flash policy
info: Error {"error":"E_VALIDATION","status":400,"summary":"1 attribute is invalid","model":"User","invalidAttributes":{"email":[{"rule":"string","message":"`undefined` should be a string (instead of \"null\", which is a object)"},{"rule":"email","message":"\"email\" validation rule failed for input: null"},{"rule":"required","message":"\"required\" validation rule failed for input: null"}]}}
[TypeError: Cannot read property 'nickname' of undefined]
verbose: Running res.view(500)...
verbose: Using layout:  /home/testhulp/Desktop/funtestgulp/views/layoutBW
verbose: Rendering view :: 500 (located @ /home/testgulp/Desktop/funtestgulp/views/500)

person Vaibhav Kumar Ambeshta    schedule 22.11.2015    source источник
comment
Можете ли вы опубликовать код своей модели пользователя, чтобы мы могли увидеть, что не так? Похоже, правило проверки для электронной почты неверно. Парус изменил API для этого между 0.10 и 0.11.   -  person Fred Stark    schedule 23.11.2015
comment
выложил пользовательскую модель. Спасибо за ответ.   -  person Vaibhav Kumar Ambeshta    schedule 23.11.2015
comment
Не похоже на проблему проверки электронной почты. Похоже, ваше приложение не передает электронное письмо для регистрации в Facebook, которое затем не соответствует требуемому правилу (и остальным тоже)   -  person Fred Stark    schedule 23.11.2015
comment
Не могли бы вы предложить решение?   -  person Vaibhav Kumar Ambeshta    schedule 23.11.2015
comment
Извините, здесь недостаточно информации, чтобы предложить решение. Можно ли регистрировать то, что передается в Sails для аутентификации? Что еще вы пробовали до сих пор? Как вы реализовали паспорт?   -  person Fred Stark    schedule 23.11.2015
comment
Вот-вот начну 3,5-часовую поездку, поэтому не могу поболтать / помочь до завтра, извините   -  person Fred Stark    schedule 23.11.2015
comment
Я предоставил всю информацию, просмотрите ее, если у вас будет время.   -  person Vaibhav Kumar Ambeshta    schedule 23.11.2015
comment
у тебя было время взглянуть на код?   -  person Vaibhav Kumar Ambeshta    schedule 24.11.2015
comment
Я застрял здесь, не могли бы вы мне помочь?   -  person Vaibhav Kumar Ambeshta    schedule 25.11.2015


Ответы (1)


У меня в config/passport.js есть это:

facebook: {
    name: 'Facebook',
    protocol: 'oauth2',
    strategy: require('passport-facebook').Strategy,
    options: {
     clientID: 'your-client-id',
     clientSecret: 'your-client-secret',
     scope: ['email'] /* email is necessary for login behavior */
}
},

Некоторое время назад я тестировал его, и он работал нормально. Вероятно, вам нужно завершить настройку faceboook, в частности, вам, вероятно, придется установить scope в файле конфигурации.

Я следил за этим сайтом в качестве ссылки:

https://www.npmjs.com/package/sails-generate-auth

Кроме того, вы должны зарегистрировать свое приложение на сайте разработчика facebook:

https://developers.facebook.com/

person Luis González    schedule 24.11.2015