1

アプリがあります。Facebookでログインしようとすると、エラーが発生します。

エラー {"error":"E_VALIDATION","status":400,"summary":"1 つの属性が無効です","model":"User","invalidAttributes":{"email":[{"rule": "string","message":"undefinedは文字列でなければなりません (オブジェクトである \"null\" ではなく)"},{"rule":"email","message":"\"email\" 検証入力のルールに失敗しました: null"},{"rule":"required","message":"\"required\" 入力の検証ルールに失敗しました: null"}]}} [TypeError: のプロパティ 'ニックネーム' を読み取れません未定義]

私のユーザーモデルは次のようになります。

/**
* 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==='dnd@testgulp.com'||(!this.email)||User.validateEmail(this.email)),'phone',this.phoneNumber)
      if(this.email==='dnd@vgulp.com'||(!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==='dnd@testgulp.com'?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='dnd@testglpu.com'
                }
                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>

「With facebook」ボタンをクリックすると、次のようなログが表示されます。

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)
4

1 に答える 1