2015-11-22 139 views
1

我有一個應用程序。當我試圖用Facebook登錄時,它會拋出錯誤。facebook登錄node.js

Error {「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:Can not讀取未定義的屬性 '綽號']

我的用戶模型是這樣的:

/** 
* 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 = /^(([^<>()[\]\\.,;:\[email protected]\"]+(\.[^<>()[\]\\.,;:\[email protected]\"]+)*)|(\".+\"))@((\[[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> 

當我點擊 「與Facebook」按鈕m得到像這樣的日誌:

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) 
+0

您可以發佈您的用戶模型代碼,以便我們可以看到有什麼不對?它看起來像電子郵件的驗證規則是錯誤的。 Sails改變了這個介於0.10和0.11之間的API –

+0

發佈了用戶模型。感謝Thanx。 –

+0

看起來不像電子郵件驗證問題。它看起來像你的應用程序沒有通過Facebook註冊電子郵件,然後通過了所需的規則(其餘的也是如此) –

回答

0

我有這個在我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/

+0

不能正常工作.... –