首页 > 解决方案 > 登录用户时遇到问题

问题描述

我收到错误 TypeError: Cannot read property 'email' of undefined 尝试登录用户并且不允许我登录。我的代码有问题吗?我的 mongo 管理员/教师模型和控制器示例(我正在使用 jwt 身份验证)

const mongoose = require('mongoose');
const { isEmail, isLength } = require('validator');
const bcrypt = require('bcryptjs');

const { Schema, model } = mongoose;

const TeacherSchema = new Schema({
  email: {
    type: String,
    unique: true,
    validate: [isEmail, 'Please enter a valid email address'],
    required: [true, 'You must provide an email address'],
  },
  password: {
    type: String,
    required: [true, 'You must provide a password'],
    validate: [(value) => isLength(value, { min: 6 }), 'Your password must be at least 6 characters long'],
  },
  dateCreated: {
    type: Date,
    default: Date.now(),
  },
  myImages:[{
    type:[Schema.Types.ObjectId],
    ref:'Image'
  }],
  myGrade:[{
    type:[Schema.Types.ObjectId],
    ref:'Grade'
  }],
  myCourses: [{
    type: [Schema.Types.ObjectId],
    ref: 'Course',
  }],
  myStocks: [{
    type: [Schema.Types.ObjectId],
    ref: 'Stock',
  }],
});

TeacherSchema.methods.toJSON = function() {
  var obj = this.toObject();
  delete obj.password;
  return obj;
};


TeacherSchema.methods.comparePassword = async function (candidatePassword) {
  const teacher = this;
  try {
    const isMatch = await bcrypt.compare(candidatePassword, teacher.password);
    return Promise.resolve(isMatch);
  } catch (e) {
    return Promise.reject(e);
  }
};

TeacherSchema.pre('save', async function (next) {
  // gets access to the user model that is currently being saved
  const teacher = this;
  if (teacher.isModified('password')) {
    try {
      const salt = await bcrypt.genSalt();
      const hash = await bcrypt.hash(teacher.password, salt);
      // overwrite the plain text password with our hash
      teacher.password = hash;
      // Finally call save
      next();
    } catch (e) {
      // Call save with an error
      next(e);
    }
  }
  next();
});

module.exports = model('Teacher', TeacherSchema);

这是控制器和路由的示例


const { isEmail, isLength } = require('validator');
const jwt = require('jwt-simple');
const axios = require('axios');
const { Teacher } = require('../models');
const { secret, GITHUB_CLIENT_SECRET } = require('../config');

function tokenForUser(teacher) {
  const timeStamp = new Date().getTime();
  return jwt.encode({ sub: teacher._id, iat: timeStamp }, process.env.SECRET || secret);
}

 

module.exports = {
  teacherSignUp: async (req, res) => {

    const {
       
      email,
      password
      
    } = req.body;
     if (!email || !password) {
      return res
        .status(422)
        .json({ error: 'You must provide email and password' });
    }
    if (!isEmail(email)) {
      return res
        .status(403)
        .json({ error: 'You must provide a valid email address' });
    }
    if (!isLength(password, { min: 6 })) {
      return res
        .status(403)
        .json({ error: 'Your password must be at least 6 characters long' });
    }
    try {
      // See if a user with the given email exists
      const existingTeacher = await Teacher.findOne({ email });
      if (existingTeacher) {
        return res
          .status(403)
          .json({ error: 'User already exists' });
      }
      const teacher = await new Teacher({
        
        email,
        password,
        
      }).save();

       const currentTeacher = await Teacher.findById(teacher._id).select('-password');
      // Eventually we will send a token
      
      return res.json({ token: tokenForUser(teacher), teacher: currentTeacher });
    } catch (e) {
      return res
        .status(403)
        .json({ e });
    }
  },
  teacherSignin: async (req, res) => {
     const currentUser = await Teacher.findOne({ email: req.teacher.email }).select('-password');
    console.log(currentUser,'current teacher email signin auth')
    res.json({ token: tokenForUser(req.teacher), teacher: currentUser });
  },
};

my route 

const router = require('express').Router(); const {teacherSignUp,teacherSignin } = require('../../../controllers/teacherAuth');

const { trequireSignIn } = require('../../../tmiddlewares/tauthMiddlewares');

// /api/tauth/teachersignup // /api/tauth/teachersignin

router.post('/teachersignup', teacherSignUp); router.post('/teachersignin', trequireSignIn, teacherSignin);

module.exports = 路由器;

我在前端的 axios 请求。(我使用 redux 形式)

import React, { Component } from 'react';
import { Field, reduxForm, SubmissionError } from 'redux-form';
import { Form, Segment, Button,Container,Image,Header,Grid,Message,Icon } from 'semantic-ui-react';
import logo from './../../components/Images/Logo.png'
import { email, required } from 'redux-form-validators';
import axios from 'axios';
import { AUTH_TEACHER} from '../../actions/types';
import './../../index.css'
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import fanuel from './../../components/Images/fanuel.jpg'
import ganesh from './../../components/Images/ganesh.png'
import vanessa from './../../components/Images/vanessa.jpeg'
import husam from './../../components/Images/husam.jpeg'
import './../../index.css'


 
class TeacherSignIn extends Component {

  onSubmit = async (formValues, dispatch) => {
      try {
      const { data } = await axios.post('/api/tauth/teachersignin', formValues);
      localStorage.setItem('token', data.token);
      dispatch({ type: AUTH_TEACHER, payload: data.token });
      this.props.history.push('/watchlist');
     } catch (e) {
       throw new SubmissionError({
        email: 'Please try again',
        password: 'You entered a bad password',
        _error: 'Login Failed'
      });
    }
  }

  
  renderEmail = ({input,meta}) => {
     return(
      <Form.Input
      {...input}
      fluid

      error={meta.touched && meta.error}
       icon='user'
      iconPosition='left'
      autoComplete='off'
      placeholder='Email Address'
      />
    )
  }
  
  renderPassword = ({ input, meta }) => {
    return (
      <Form.Input
        {...input}
        error={meta.touched && meta.error }
        fluid
        type='password'
        icon='lock'
        placeholder='password'
        autoComplete='off'
        iconPosition='left'
      />
    );
  }

  render(){
    const {handleSubmit,invalid,submitting,submitFailed}=this.props
    return(
 <div>
   <Helmet>
   <style>{'body { background-color: #532f8c; }'}</style>

         </Helmet>
   {/* <div className='j2'>
 <Image style={{backgroundColor:'white'}} className='im2'src={logo}/>
  
 </div> */}
 
 <Grid textAlign="center" style={{ height: '85vh',margin:'0px 0 25px 0' }} verticalAlign="middle">
          <Grid.Column style={{ maxWidth: 500}}>

  
 
      <Form   size='large' onSubmit={handleSubmit(this.onSubmit)}>
      <Segment style={{backgroundColor:'#f7f8fa'}} >

         <Header color="grey" textAlign="center" style={{ fontSize: '34px' }}>
              <Image style={{backgroundColor:'white'}} className='im'src={logo} />
              Log-in to your account
            </Header>
             <Field
           name='email'
          component={this.renderEmail}
          validate={[
            required({msg:'Email is required'}),
            email({ msg: 'You must provide a valid email address' })
          ]}
          />
 

 
          <Field
          name='password'
          component={this.renderPassword}
          validate={[
            required({msg:'you must provide a password'})
          ]}
          />
          <Button
          content='Sign In'
          color='purple'
          fluid
          size='large'
          type='submit'
          disabled={invalid || submitting || submitFailed}
          />
                 </Segment>

       </Form>
        <Message style={{backgroundColor:'#f7f8fa'}}>
              New to the site?
              <Button as={Link} to="/signup" color="purple" size="small" compact style={{ marginLeft: '5px' }}>Sign Up Here</Button>
            </Message>
      </Grid.Column>
</Grid>

     
<div className='div-tag1'style={{backgroundColor:'#222222'}}>
    <Container>
<Segment vertical>

     <Grid columns={3} divided>
    <Grid.Row>
      <Grid.Column>
          <h1 style={{color:'white'}}className='how-it-works'>10/10 Stock Tracker</h1>
          <div><p style={{color:'white',fontSize:'1.25rem',fontFamily:'"Helvetica Neue",Helvetica,Arial,sans-serif'}}>
          This application is a helpful tool to save stocks onto a personal watchlist. It provides information on the stock markets top 10 winners and losers of the day. Users can also search and track any stock in the market and view stocks that are trending among other users.

</p></div>
      </Grid.Column>
      <Grid.Column>
 
 <h1 style={{color:'white'}}className='how-it-works'>      Get Started
</h1>
<p  style={{color:'white',fontSize:'1.25rem',fontFamily:'"Helvetica Neue",Helvetica,Arial,sans-serif'}}> Get access to your Watchlist by creating an account.
</p>
 <Link
as={Link} to='/signup'>
<Button color='purple'> Register Now</Button>

</Link>
        </Grid.Column>
      <Grid.Column>
      <h1 style={{color:'white'}}className='how-it-works'> Contact Us</h1> 
      <p  style={{color:'white',fontSize:'1.25rem',fontFamily:'"Helvetica Neue",Helvetica,Arial,sans-serif',marginBottom:'10px'}}> <span  >  <a href='mailto:fanuelnalem@outlook.com'  style={{color:'white'}}   >  <Icon name='mail'></Icon>Send Feedback</a> </span></p>  

      
       <h1 className='how-it-works'style={{color:'white',marginTop:'0',marginBottom:'18px'}}>
       Developed By
       </h1>  
       <div> 
           <Grid>

            <Grid.Row columns={4}>
      <Grid.Column>
        <Image className='img' src={vanessa} />
      </Grid.Column>
      <Grid.Column>
        <Image className='img'src={husam} />
      </Grid.Column>
      <Grid.Column>
        <Image className='img'src={fanuel} />
      </Grid.Column>
      <Grid.Column>
        <Image className='img'src={ganesh} />
      </Grid.Column>
    </Grid.Row>
    </Grid>

    </div>
           

      </Grid.Column>
    </Grid.Row>
    </Grid>
     
    </Segment>
     <p style={{backgroundColor:'rgb(55, 55, 59)',padding:'10px',borderRadius:'5px',color:'white',fontSize:'1.25rem',fontFamily:'"Helvetica Neue",Helvetica,Arial,sans-serif' }}className='p-tag' >Copyright 2020. All rights reserved.</p>

      </Container>


      

</div> 

</div>
    )
  }
   
}
export default reduxForm({ form: 'tsignin' })(TeacherSignIn);

标签: mongodbtypeerrorredux-form

解决方案


推荐阅读