0

我在 Nodejs 中编写了一个 API,它有助于使用 Mysql 数据库重置密码。它在 Postman 中工作正常。我在 Expo IOS App 中调用了这个 API。但是我收到网络请求失败错误。下面是Node js程序:

应用程序.js:

var express = require('express');
var path = require('path');
var connection = require('./database.js');
var nodemailer = require('nodemailer');
const bcrypt = require("bcryptjs")

var randtoken = require('rand-token');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var flash = require('express-flash');
var session = require('express-session');
var bodyParser = require('body-parser');

const createError = require('http-errors');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');

var app = express();
var connection = require('./database.js');
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))

//send email
function sendEmail(email, token) {
var email = email;
var token = token;
var mail = nodemailer.createTransport({
service: 'gmail',
auth: {
user: 'c***********@gmail.com', // Your email id
pass: '**********' // Your password
}
});
var mailOptions = {
from: 'poornima@abccompany.com',
to: email,
subject: 'Reset Password Link - ABCCompany.com',
html: '<p>You requested for reset password, kindly use this <a 
href="http://localhost:4000/reset-password?token=' + token + '">link</a> to reset 
your password</p>'
};
mail.sendMail(mailOptions, function(error, info) {
if (error) {
console.log(1)
} else {
console.log(0)
}
});
}

app.post('/reset-password-email', function(req, res, next) {
var email = req.body.email;
console.log('email from api '+email);
connection.query('SELECT * FROM JTGDB.UserInfo WHERE email ="' + email + '"', 
function(err, result) {
 if (err) throw err;
 var type = ''
 var msg = ''
 console.log(result[0]);
 if (result[0].Email.length > 0) {
 var token = randtoken.generate(20);
 var sent = sendEmail(email, token);
 if (sent != '0') {                                                                                  
 var data = {
  token: token
 }
 connection.query('UPDATE JTGDB.UserInfo SET ? WHERE email ="' + email + '"', data, 
 function(err, result) {
 if(err) throw err
 })
 type = 'success';
 msg = 'The reset password link has been sent to your email address';
 } else {
 type = 'error';
 msg = 'Something goes to wrong. Please try again';
 }
 } else {
  console.log('2');
 type = 'error';
 msg = 'The Email is not registered with us';
 }
 res.redirect('/');
 });
 })

 // view engine setup
 app.set('views', path.join(__dirname, 'views'));
 app.set('view engine', 'ejs');

 app.use(logger('dev'));
 app.use(express.json());
 app.use(express.urlencoded({ extended: false }));
 app.use(cookieParser());
 app.use(express.static(path.join(__dirname, 'public')));

 app.use(session({ 
secret: '123458cat',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60000 }
 }))

 app.use(flash());
 app.use('/', usersRouter);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});

// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};

// render the error page
res.status(err.status || 500);
res.render('error');
});

app.listen(4000, function () {
console.log('Node app is running on port 4000');
});

module.exports = app;

下面是 IOS App ForgetPassword Screen 页面:

ForgetPasswordScreen.js:

import React, { Component, Fragment, useState } from "react";
import { View, Text,SafeAreaView, Image, StyleSheet } from "react-native";
import { Formik } from "formik";
import * as Yup from "yup";
import FormInput from "../../components/UI/FormInput";
import FormButton from "../../components/UI/FormButton";
import ErrorMessage from "../../components/UI/ErrorMessage";
import * as authActions from '../../store/actions/auth';
import {useDispatch} from "react-redux";
import Toast from 'react-native-root-toast';

const validationSchema = Yup.object().shape({
email: Yup.string()
.label("Email")
.email("Enter a valid email")
.required("Please enter a registered email"),
});

const ForgotPasswordScreen = props => {
const [isLoading,setIsLoading] = React.useState(false);
const [error, setError] = React.useState('');
const dispatch = useDispatch();
const handlePasswordReset = async (values, actions) => {
const { email } = values;
console.log('email is '+email);
let action
action =  authActions.resetpassword(
         email
         );
setError(null);
setIsLoading(true);
     try{
      await dispatch(action);
  props.navigation.navigate("Login");
} catch (error) {
  actions.setFieldError("general", error.message);
}
};
return (
  <SafeAreaView>
    <View style={styles.emailiconview}>
    <Image source={require('../../assets/reset_email.png')} />
    </View>
     <View style ={styles.instrview1}>
       <Text>
         Please enter your registered email address below to 
       </Text>
       </View>
     <View style={styles.instrview2}>
       <Text>receive password reset instruction</Text>
     </View>
     <View style={styles.emailinputview}>
     <Formik
      initialValues={{ email: "" }}
      onSubmit={(values, actions) => {
      handlePasswordReset(values, actions);
      }}
      validationSchema={validationSchema}
    >
      {({
        handleChange,
        values,
        handleSubmit,
        errors,
        isValid,
        touched,
        handleBlur,
        isSubmitting,
      }) => (
        <Fragment>
          <FormInput
            name="email"
            value={values.email}
            onChangeText={handleChange("email")}
            placeholder="Enter email"
            autoCapitalize="none"
            iconName="ios-mail"
            iconColor="blue"
            onBlur={handleBlur("email")}
          />
          <ErrorMessage errorValue={touched.email && errors.email} />
          <View style={styles.buttonContainer}>
            <FormButton
              buttonType="outline"
              onPress={handleSubmit}
              title="Send Email"
              buttonColor="blue"
              disabled={!isValid || isSubmitting}
            />
          </View>
          <ErrorMessage errorValue={errors.general} />
        </Fragment>
      )}
    </Formik>
    </View>
  </SafeAreaView>
  )
  }

  const styles = StyleSheet.create({
  container: {
  flex: 1,
  backgroundColor: "#fff",
  marginTop: 150,
  },
  text: {
  color: "#333",
  fontSize: 24,
  marginLeft: 25,
  },
buttonContainer: {
margin: 25,
},
emailiconview:{
justifyContent:'center',
alignItems:'center',
top:"30%"
},
instrview1:{
top:'40%',
justifyContent:'center',
alignSelf:'center'
},  instrview2:{
top:'45%',
justifyContent:'center',
alignSelf:'center'
},
 emailinputview:{
top:'50%'
}
});
export default ForgotPasswordScreen;

下面是我获取 API 的商店身份验证:

auth.js:

import Device from '../../model/Device';
import AsyncStorage from '@react-native-async-storage/async-storage'

export const FORGOTPASSWORD = 'FORGOTPASSWORD';


export const resetpassword=(email) =>{
console.log(email);
return async dispatch =>{
  const response = await fetch(
    'http://my_IPV4_Address:4000/reset-password-email',
    {
     method: 'POST',
     header: {
       'Content-Type': 'application/json',
     },
     body: JSON.stringify({
      email: email
     })      
    }
  );
  const resData = await response.text();
   console.log(resData);
  dispatch({type:FORGOTPASSWORD}); 
};
}

运行此程序后,我在 Expo 中收到以下错误:

网络请求失败

它正在接收电子邮件,但没有点击 api。

email is cpoornima.1987@gmail.com
Email id to API cpoornima.1987@gmail.com

我在 NodeJs 中遇到以下错误:

email from api undefined
undefined

我已经添加了

     <key>NSAppTransportSecurity</key>
     <dict>
     <key>NSAllowsArbitraryLoads</key>
     <true/>
     </dict>

到 Info.plist。我只是在检查附加到 Expo App 的 IOS 模拟器。如何度过这个难关?

4

1 回答 1

0

下面是运行良好的 auth.js 获取 API。只要我按下发送电子邮件按钮,就会有一封电子邮件提供电子邮件 ID,以便使用真实的 Iphone 设备重置密码。

auth.js:

import Device from '../../model/Device';
import AsyncStorage from '@react-native-async-storage/async-storage'

export const FORGOTPASSWORD = 'FORGOTPASSWORD';

export const resetpassword=(email) =>{
const formData = new FormData();
formData.append('email',email);
console.log('Email id to API '+email);
return async dispatch =>{
  fetch('http://My_IPV4_Address:4000/reset-password-email',
    {
      method: 'POST',
      headers: {
        Accept: 'application/json',
        'Content-Type': 'application/json',
      },
      body:JSON.stringify({
        email: email,
      }),
    })
    .then(res => res.text())
    .then(
      (signupresult) =>{
  
      }).catch(err =>{
        console.log(err);
      })
      dispatch({type:FORGOTPASSWORD});
      };
      }
于 2022-02-08T14:32:22.150 回答