passport.authenticate('local') 在 Passport-Local Mongoose 中似乎不起作用

passport.authenticate('local') in Passport-Local Mongoose seems doesn't work

我正在使用 Passport-Local Mongoose 对用户进行身份验证,但遇到了问题。 我认为应该没有任何问题,但是当我测试登录时,服务器 returns '400 bad request'.

我想不出任何问题,但我希望有人能做到。

这是我的'server.js'(只有相关代码)。

import session from 'express-session';
import cookieParser from 'cookie-parser';
import passport from 'passport';
import User from './models/user.model';

app.use(cookieParser());
app.use(session({
  secret: 'my secret',
  resave: false,
  saveUninitialized: false,
}));

app.use(passport.initialize());
app.use(passport.session());

passport.use(User.createStrategy());
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

import UserRouter from './api/user.router';

app.use(UserRouter);

和'user.model.js':

import mongoose from 'mongoose';
import passportLocalMongoose from 'passport-local-mongoose';

const Schema = mongoose.Schema;

const userSchema = new Schema({
  email: { type: String, required: true },
  password: { type: String, required: true },
  lastLogin: { type: Number, default: Date.now, required: true },
});

userSchema.plugin(passportLocalMongoose, {
  usernameField: 'email',
  lastLoginField: 'lastLogin',
  hashField: 'password',
});

export default mongoose.model('User', userSchema);

和'user.router.js':

import { Router } from 'express';
import User from '../models/user.model';
import passport from 'passport';

const router = new Router();

router.post('/api/login',
  passport.authenticate('local'),
  (req, res) => {
    res.json({ user: req.user });
  }
);

最后 'LoginModal.jsx' :

import React, { PropTypes } from 'react';
import CustomModal from '../Common/CustomModal';
import { browserHistory } from 'react-router';

class LoginModal extends React.Component {
  constructor(props) {
    super(props);
    this.displayName = 'LoginModal';
    this.state = {
      showModal: this.props.show,
      email: '',
      password: '',
    };
    this._handleInputChange = this._handleInputChange.bind(this);
    this._handleOnLoginClick = this._handleOnLoginClick.bind(this);
  }
  _handleInputChange(e) {
    this.setState({
      [e.target.name]: e.target.value,
    });
  }
  _handleOnLoginClick() {
    const formData = new FormData();
    formData.append('email', this.state.email);
    formData.append('password', this.state.password);
    request.post('/api/login')
    .send(formData)
    .end((err, res) => {
      if (err || !res.user) {
        browserHistory.push('/');
      } else {
        browserHistory.push('/');
      }
    });
  }
  render() {
    const bodyComponent = () => {
      return (
        <fieldset>
          <label className="block clearfix">
            <span className="block input-icon input-icon-right">
            <input type="text" className="form-control" placeholder="E-MAIL"
              name="email" value={this.state.email} onChange={this._handleInputChange}
            />
            <i className="ace-icon fa fa-user"></i>
          </span>
          </label>
          <label className="block clearfix">
            <span className="block input-icon input-icon-right">
            <input type="password" className="form-control" placeholder="PASSWORD"
              name="password" value={this.state.password} onChange={this._handleInputChange}
            />
            <i className="ace-icon fa fa-lock"></i>
          </span>
          </label>
        </fieldset>
      );
    };
    const footerComponent = () => {
      return (
        <div className="clearfix" style={{ textAlign: 'left' }}>
          <label className="inline" style={{ marginTop: '6px' }}> <input type="checkbox" className="ace" name="remember" value="yes"/>
            <span className="lbl"> REMEMBER ME</span>
          </label>
          <button type="button" className="width-35 pull-right btn btn-sm btn-primary" onClick={this._handleOnLoginClick}>
            <i className="ace-icon fa fa-key"></i> <span className="bigger-110">LOGIN</span>
          </button>
        </div>
      );
    };
    return (
      <div>
        <CustomModal show={this.state.showModal}
          title="LOGIN"
          bodyComponent={bodyComponent()}
          footerComponent={footerComponent()}
          width="300px"
          close={this.props.close}
          backdrop
        />
      </div>
    );
  }
}

我自己发现了。 passport.authenticate() 函数似乎不支持 'form-data' 内容类型。

我使用 'FormData.js' 发送登录数据,它在 'LoginModal.jsx' 发送数据设置内容类型为 'form-data'。

我像下面这样更改了这些代码并且它起作用了。

$.ajax({
  url: '/api/login',
  type: 'post',
  data: { email: this.state.email, password: this.state.password },
  success: () => {
    browserHistory.push('/login-success');
  },
  error: (err) => {
    console.log(err);
  }
});