向 Flask 服务器发送 POST 请求的响应没有返回所需的值

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

我正在为小型项目创建后端服务器(任何安全问题都不是问题)并偶然发现了一个问题。我必须将 JWT 令牌发送到前端,但显然令牌没有到达。这是我的 Flask 服务器的代码:

@app.route('/api/user/login', methods=['POST'])
def login():
    cursor = db.cursor()
    data = request.get_json()
    username = data.get('username')
    pw_hash = data.get('pw_hash')
    
    cursor.execute('SELECT pw_hash, id FROM users WHERE username=\'{username}\';')
    data = cursor.fetchone()

    db.commit()
    if data and pw_hash == data[0]:
        return jsonify({'token': create_access_token(identity={'id': data[1]})}), 201
    return jsonify({'error':'Invalid credentials.'}), 401

这是 React 前端的代码:

import React, { useState } from 'react';
import CryptoJS from 'crypto-js';

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

    const handleSubmit = async (e) => {
        const payload = {
            username: username,
            pw_hash: CryptoJS.SHA256(password).toString(),
        };

        try {
            const response = await fetch('/api/user/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload),
            });

            if (response.ok) {
                alert('로그인에 성공했습니다.');
                localStorage.setItem('token', response.json().token);
            } else {
                alert('로그인에 실패했습니다.');
            }
        } catch(error) {
            alert('서버 오류');
        }
    }

    return (
        <div>
        // ...
        </div>
    );
};

export default Login;

我希望至少能从后端得到一些东西,但是

console.log(reponse.json().token)
返回
undefined

感谢您提前的帮助。


编辑:

这是前端的修改代码。

import React, { useState } from 'react';
import CryptoJS from 'crypto-js';

const Login = () => {
    const [username, setUsername] = useState('');
    const [password, setPassword] = useState('');
    const [data, setData] = useState('');

    const handleSubmit = async (e) => {
        const payload = {
            username: username,
            pw_hash: CryptoJS.SHA256(password).toString(),
        };

        try {
            const response = await fetch('/api/user/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload),
            });
            const json = await response.json();
            setData(json);

            if (response.ok && data) {
                alert('로그인에 성공했습니다.');
                localStorage.setItem('token', data);
                alert(data.token);
            } else {
                alert('로그인에 실패했습니다.');
            }
        } catch(error) {
            alert('서버 오류');
        }
    }

    return (
        <div>
        ...
        </div>
    );
};

export default Login;
reactjs flask jwt frontend backend
1个回答
0
投票

我根据你的代码写了一个简单的例子。代码修改了两个地方。我认为关键的区别在于数据库查询的代码。您的查询没有为我产生任何结果。

from flask import (
    Flask, 
    current_app, 
    g, 
    jsonify, 
    request
)
from flask_jwt_extended import (
    JWTManager, 
    create_access_token
)
import sqlite3

DATABASE = 'database.db'

app = Flask(__name__)
app.secret_key = 'your secret here'

jwt = JWTManager(app)

def get_db():
    db = getattr(g, '_database', None)
    if db is None:
        db = g._database = sqlite3.connect(DATABASE)
    return db

@app.teardown_appcontext
def close_connection(exception):
    db = getattr(g, '_database', None)
    if db is not None:
        db.close()

with app.app_context():
    try:
        db = get_db()
        with current_app.open_resource('schema.sql', 'r') as f:
            db.executescript(f.read())
        db.commit()
    except: pass

@app.post('/api/user/login')
def login():
    username = request.json.get('username', None)
    password = request.json.get('pw_hash', None)

    cursor = get_db().cursor()
    cursor.execute('SELECT pw_hash, id FROM users WHERE username=?', (username,))
    data = cursor.fetchone()
    cursor.close()

    if data and password == data[0]:
        return jsonify({'token': create_access_token(identity={'id': data[1]})}), 201

    return jsonify({'error': 'Invalid credentials.'}), 401
import React, { useState } from 'react';
import CryptoJS from 'crypto-js';

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

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

        const payload = {
            username: username,
            pw_hash: CryptoJS.SHA256(password).toString(),
        };

        try {
            const response = await fetch('/api/user/login', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload),
            });

            const data = await response.json();
            if (response.ok && data) {
                alert('로그인에 성공했습니다.');
                localStorage.setItem('token', data.token);
                console.log(data.token);
            } else {
                alert('로그인에 실패했습니다.');
            }
        } catch(error) {
            console.error('서버 오류');
        }
    }

    return (
        <div>
            <form onSubmit={handleSubmit}>
                <input type="text" name="username" onChange={(e) => setUsername(e.target.value)} />
                <input type="password" name="password" onChange={(e) => setPassword(e.target.value)} />
                <button type="submit">Login</button>
            </form>
        </div>
    );
};

export default Login;
© www.soinside.com 2019 - 2024. All rights reserved.