node.js - 使用 Node.js 登录 Facebook

标签 node.js facebook sails.js passport.js passport-facebook

我有一个应用程序。当我尝试使用 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"}]}} [类型错误:无法读取未定义的属性“昵称”]

我的用户模型如下所示:

/**
* 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)

最佳答案

我的 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 */
}
},

我前段时间测试过,效果很好。您可能需要完成 Facebook 配置,特别是您可能必须在配置文件中设置范围

我引用了这个网站:

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

此外,您必须在 Facebook 开发者网站中注册您的应用程序:

https://developers.facebook.com/

关于node.js - 使用 Node.js 登录 Facebook,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33855418/

相关文章:

node.js - 从 API 路由 Next.js 上传文件不起作用

facebook - 有没有办法使用 Marketing API 更新 FB 广告 URL 参数?

javascript - 分隔数组的水线查询 "OR"

sails.js - 在sails.js 中处理生产/开发/测试配置

node.js - 如何通过apache连接 Node 服务器?

javascript - node.js 字体无法正常工作并且没有显示错误

Android Facebook SDK 3.2获取个人资料电子邮件信息显示为空

c# - 使用 facebook graph api 时,远程服务器返回错误 : (404) Not Found.

node.js - 如何在没有网络服务器(使用任何端口)的情况下运行 sails 控制台?

node.js - 将查询条件传递给生成查询字符串的 Node.js/Mongodb 中的 db.collection.find