react + passport + express axios post 出现 302 错误

问题描述 投票:0回答:0

我用 express 制作了一个简单的 api,并用 react 制作了一个简单的前端。当我通过 react 向 express /login 路径发送带有 axios 的登录请求时,我收到 302 错误。以前它是有效的,但我的护照会话没有持续存在,我读到 axios 默认情况下不发送凭据,所以当我将 axios.defaults.withCredentials 更改为 true 时它坏了,现在在提交登录表单时给我一个 302 错误

快递应用程序.js:

const express = require('express');
const { registerUser } = require('./routeFunctions')
const session = require('express-session')
const passport = require('passport');
const bcrypt = require('bcrypt')
const LocalStrategy = require('passport-local').Strategy
const { checkAuthenticated, getUserFromDBByUsername, getUserFromDB, getPokemon } = require('./helper')
const dotenv = require('dotenv').config
const bodyParser = require('body-parser')
const cors = require('cors')

const app = express()
const port = 5000
const secret = process.env.SECRET

const corsConfig = {
    origin: true,
    Credentials: true,
}

app.use(bodyParser.urlencoded())
app.use(express.text())
app.use(cors(corsConfig))
app.options('*', cors(corsConfig))


app.use(session({
    secret: secret,
    cookie: {maxAge: 60 * 60 * 1000, sameSite: 'none', httpOnly: true, secure: false},
    saveUninitialized: false,
    resave: false
}));

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

passport.serializeUser((user, done) => {
    done(null, user.user_id)
})

passport.deserializeUser((id, done) => {
    user = getUserFromDB(id, async (user) => {
        if (!user) {
            return done(null, false);
        }
        return done(null, user);
    });
    
})

passport.use(new LocalStrategy( async (username, password, done) => {
    getUserFromDBByUsername(username, async (user) => {
        user = user[0]
        try {
            if (!user) {
                return done(null, false)
            }
            const passwordMatched = await bcrypt.compare(password, user.password);
            if (passwordMatched) {
                console.log('password matched')
                return done(null, user)
            } else {
                return done(null, false)
            }
        } catch(error) {
            console.log(error)
        }
        })     
    })
);

app.get('/home', (req, res) => {
    getPokemon((results) => {
        res.json(results)
    })
})

app.get('/', (req, res) => {
    res.set({"Content-Type": "application/json"})
    res.json({authorized: false})
})

app.get('/auth', (req, res) => {
    console.log(req.session)
    res.set({"Content-Type": "application/json"})
    res.json({authorized: true})
})

app.post('/login', passport.authenticate('local', { failureRedirect: '/'}),
 (req, res) => {
    console.log(req.session)
    res.redirect('/auth')
})

app.post('/register', registerUser)




app.listen(port, () => {
    console.log(`app running on port ${port}`)
})

helper.js:

const mysql = require('mysql2');

const user = process.env.USER;
const pass = process.env.PASSWORD

const con = mysql.createConnection({
    host: 'localhost',
    database: 'pokemon_prototype_db',
    user: user,
    password: pass
});


const getPokemon = (callback) => {
    const results = con.query(`
        SELECT pokemon_users.is_caught,
            pokemon.pokemon_id,
            pokemon.pokemon_name,
            pokemon.region,
            pokemon.type 
        FROM pokemon_users
        INNER JOIN pokemon On pokemon_users.pokemon_id = pokemon.pokemon_id 
        where user_id = ?
        `, 42, (error, results) => {
        if (error) {
            throw (error)
        } else {
            return callback(results)
        }
    })

}

const checkAuthenticated = (req, res, next) => {
    if (req.isAuthenticated()) {
        return next()
    }
    console.log(req.isAuthenticated())
    res.redirect('/')
};

const getUserFromDB = (id, callback) => {
    const results = con.query('SELECT * FROM users WHERE user_id = ?', [id], (error, results) => {
        if (error) {
            throw (error)
        }
        return callback(results)
    });
    return callback(results)
};

const getUserFromDBByUsername = (username, callback) => {
    con.query('SELECT * FROM users WHERE username = ?', username, (err, results) => {
        if (err) {
            throw(err)
        }
        return callback(results)
    });
};


module.exports = {
    checkAuthenticated,
    getUserFromDB,
    getUserFromDBByUsername,
    getPokemon
}

反应 App.js:

import { useState, useEffect } from "react";
import { useNavigate, Route, Routes, BrowserRouter, Navigate, Link } from 'react-router-dom'
const { LoginForm } = require("./login.jsx")
const { Register } = require("./register.jsx")
const { Home } = require('./Home.jsx')



const App = () => {



    return (
        <>
            <BrowserRouter>
                <Routes>
                    <Route exact path="/login" element={<LoginForm/>}/>
                    <Route exact path="/register" element={<Register/>}/>
                    <Route exact path="/home" element={<Home/>}/>
                </Routes>
            </BrowserRouter>
        </>
    )

    
    
}


export default App`

反应登录.jsx:

import axios from 'axios';
import { react, useState, useEffect } from 'react'
import { useNavigate, Link } from 'react-router-dom';

const LoginForm = () => {
    const navigate = useNavigate()
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');


     const loginUser = async (e) => {
        e.preventDefault();

        const body = {
            username: username,
            password: password
        }
    
        axios.defaults.baseURL = ''
        axios.defaults.withCredentials = true
        const loggedIn = await axios.post("http://localhost:5000/login", body, {
            headers: {
                "Content-Type": "application/x-www-form-urlencoded"
            }
        })
        .then((response) => {return response.data})
        .catch(err => {
            throw (err)
        });
        console.log(loggedIn)
        if (loggedIn.authorized === true) {
            return navigate("/home")
        } else {
            console.log('this isnt working')
        }
       
    } 


    return (
        <>
            <div>
                <form onSubmit={loginUser}>
                    <input value={username} onChange={(e) => setUsername(e.target.value)} type='text'></input><br/>
                    <input value={password} onChange={(e) => setPassword(e.target.value)} type='password'></input><br/>
                    <button type="submit">Login</button><br/>
                </form>
                <Link to="/register">register</Link>
            </div>
        </>
    )

}

export {LoginForm} 

它在没有将 axios.defaults.withCredentials 设置为 true 的情况下工作,但是我无法实现对我的端点的授权,因为会话中的 passport 元素在没有设置为 true 的情况下不会持续存在。与邮递员一起测试时,后端也按预期工作

reactjs express axios passport.js
© www.soinside.com 2019 - 2024. All rights reserved.