需要了解passport.js本地策略

Posted

技术标签:

【中文标题】需要了解passport.js本地策略【英文标题】:Needs to understand passport.js local strategy 【发布时间】:2018-11-10 09:53:35 【问题描述】:

我正在尝试在护照策略中的 usernameField 中添加电话,以便用户也可以使用电话号码和电子邮件登录,但在互联网上搜索后有点坚持如何做到这一点 - 阅读 passport.js 文档不是对我有任何意义。 Q1:我应该更改我的 schemamongoose 模型还是因为我无法在护照本地策略中添加第三个字段。

import  mongoose from 'mongoose';
import  Router  from 'express';
import Account from '../model/account';
import bodyParser from 'body-parser';
import passport from 'passport';

import generateAccessToken, respond, authenticate from '../middleware/authMiddleware';

api.post('/register', (req, res) => 
  Account.register(new Account(
    username: req.body.email,
    phoneNumber: req.body.phoneNumber,
    myId: req.body.myId,
    termsandcondition: req.body.termsandcondition,

    verifiedEmailCode: uuid()
  ), req.body.password, function(err, account) 

    if (err) 
      return res.json(
                        "status": false,
                        "code" : 500,
                        "message": 'An error occurred: ' + err
                      );
    

    passport.authenticate(
      'local', 
        session: false
    )(req, res, () => 
      // send email
      const confirmUrl = `$config.siteUrl/api/v1/account/register/verifyemail?token=$req.user.verifiedEmailCode`;
      gmail.sendMail(
        from: config.gmail.user,
        to: req.user.username,
        subject: 'Please confirm your email with Beamlive',
        html: `<a href="$confirmUrl">Please confirm your email with mylive</a>`,
        auth: 
          user: config.gmail.user,
          refreshToken: config.gmail.refreshToken,
          accessToken: config.gmail.accessToken
        
      , (err, info) => 
        if(err) 
          console.log('error sending email', err);
          return;
        
          console.log('successfully sent registration email');
      )


      )
      .then(message => 

      )
      .done();
      res.json(
                 "User":"UserID": req.user.username,
                         "PhoneNumber": req.user.phoneNumber,
                         "myId": req.user.beamId.IdOne,
                         "termsandcondition": req.user.termsandcondition
                          ,
                 "status": true,
                 "code": 200,
                 "message": 'You have successfully registered with  mylive'
      );

      );
    );
  );

  api.post('/login', (req, res, next) => passport.authenticate(
    'local', 
      session: false,
      scope: []
    , (err, user, info) => 
      if(err) 
        return next(err);
      

      if(!user.verifiedEmail && !user.verifiedPhone) 
        return res.json( "status": false, "code": 403, "message": "You need to verify your email or Phone number" );
      

      req.logIn(user, next);
    )(req, res, next), generateAccessToken, respond);

  return api;

//认证中间件:

import jwt from 'jsonwebtoken';
import expressJwt from 'express-jwt';

const TOKENTIME = 60*60*24*30 // 30 days
const SECRET = "server key will go here";

let authenticate = expressJwt( secret : SECRET )

let generateAccessToken = (req, res, next) => 
  req.token = req.token || ;
  req.token = jwt.sign(
    id: req.user.id,
  , SECRET, 
    expiresIn: TOKENTIME// 30 days
  );
  next();


let respond = (req, res) => 
  res.status(200).json(
    user: userID: req.user.username,
    token: req.token,
    tokenTime: TOKENTIME,
    status: true,
    code: 200,
    message: 'User logged In'
  );


module.exports = 
  authenticate,
  generateAccessToken,
  respond
;

//Index.js:

app.use(passport.initialize());
let Account = require('./model/account');
passport.use(new LocalStrategy(
  usernameField: 'email',
  passwordField: 'password'
,
  Account.authenticate()
));
passport.serializeUser(Account.serializeUser());
passport.deserializeUser(Account.deserializeUser());

//架构mongodb:

import passportLocalMongoose from 'passport-local-mongoose';

let Account = new Schema(

phoneNumber: String,
email: String,
password: String

Account.plugin(passportLocalMongoose);
module.exports = mongoose.model('Account', Account);

【问题讨论】:

【参考方案1】:

passport-local-mongoose 库允许您在添加插件时传递一些选项,其中一个选项是 usernameQueryFields,根据文档:

usernameQueryFields:指定用于识别用户的模型的替代字段(例如电子邮件)。

因此,为了使用 phoneNumber 字段,您应该能够执行以下操作:

let Account = new Schema(
  phoneNumber: String,
  email: String,
  password: String
);

Account.plugin(passportLocalMongoose,  usernameQueryFields: ["phoneNumber", "email"] );
module.exports = mongoose.model("Account", Account);

【讨论】:

以上是关于需要了解passport.js本地策略的主要内容,如果未能解决你的问题,请参考以下文章

Passport.js本地策略如何保护路线

使用 passport.js 将本地策略连接到另一个(Facebook、Twitter、Google 等)

passport.js 中的本地和 Google 策略:序列化用户时的问题

在node.js的护照库中应该使用什么策略

Passport.js 使用 failureRedirect 呈现错误 401

在集成测试中模拟不同的 passport.js 策略