I am getting this error while trying to integrate front end in reactjs and backend in python flask.
Access to XMLHttpRequest at 'http://localhost:5000/api/auth/login' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Below is my flask code where I have tried to handle the header in app.py file:
from flask import Flask, request, session, redirect, url_for, render_template, flash, jsonify
import psycopg2
import psycopg2.extras
from werkzeug.security import generate_password_hash, check_password_hash
from flask_cors import CORS
app = Flask(__name__)
CORS(app, supports_credentials=True) # This will enable CORS for all routes
app = Flask(__name__)
app.secret_key = 'secretkey'
DB_HOST = "localhost"
DB_NAME = "Dbname"
DB_USER = "user"
DB_PASS = "password"
conn = psycopg2.connect(dbname=DB_NAME, user=DB_USER, password=DB_PASS, host=DB_HOST)
@app.route('/')
def home():
if 'loggedin' in session:
if request.headers.get('Content-Type') == 'application/json':
return jsonify({'username': session['username']})
return render_template('home.html', username=session['username'])
return jsonify({'message': 'User not logged in'})
@app.route('/api/auth/login', methods=['POST','OPTIONS'])
def api_login():
# Your login logic here
# Make sure to handle the request and return the appropriate response
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
if request.method == 'OPTIONS':
response = jsonify()
response.headers['Access-Control-Allow-Origin'] = 'http://localhost:3000'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization'
response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE'
return response, 200
# Check if it's an AJAX request
if request.headers.get('Content-Type') == 'application/json':
data = request.get_json()
username = data.get('username')
password = data.get('password')
cursor.execute('SELECT * FROM users WHERE username = %s', (username,))
account = cursor.fetchone()
if account and check_password_hash(account['password'], password):
session['loggedin'] = True
session['id'] = account['id']
session['username'] = account['username']
return jsonify({'message': 'Login successful', 'username': account['username']})
else:
return jsonify({'message': 'Incorrect username/password'})
return jsonify({'message': 'Invalid request'})
@app.route('/login', methods=['POST'])
def login():
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
# Check if it's an AJAX request
if request.headers.get('Content-Type') == 'application/json':
data = request.get_json()
username = data.get('username')
password = data.get('password')
cursor.execute('SELECT * FROM users WHERE username = %s', (username,))
account = cursor.fetchone()
if account and check_password_hash(account['password'], password):
session['loggedin'] = True
session['id'] = account['id']
session['username'] = account['username']
return jsonify({'message': 'Login successful', 'username': account['username']})
else:
return jsonify({'message': 'Incorrect username/password'})
return jsonify({'message': 'Invalid request'})
@app.route('/register', methods=['POST'])
def register():
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
# Check if it's an AJAX request
if request.headers.get('Content-Type') == 'application/json':
data = request.get_json()
fullname = data.get('fullname')
username = data.get('username')
password = data.get('password')
email = data.get('email')
CnrNumber = data.get('CnrNumber')
phonenumber = data.get('phonenumber')
_hashed_password = generate_password_hash(password)
cursor.execute('SELECT * FROM users WHERE username = %s', (username,))
account = cursor.fetchone()
if account:
return jsonify({'message': 'Account already exists!'})
cursor.execute('INSERT INTO users (fullname, username, password, email, CnrNumber, phonenumber) VALUES (%s, %s, %s, %s, %s, %s)',
(fullname, username, _hashed_password, email, CnrNumber, phonenumber))
conn.commit()
return jsonify({'message': 'Registration successful'})
return jsonify({'message': 'Invalid request'})
@app.route('/logout')
def logout():
# Check if it's an AJAX request
if request.headers.get('Content-Type') == 'application/json':
session.pop('loggedin', None)
session.pop('id', None)
session.pop('username', None)
return jsonify({'message': 'Logout successful'})
# Redirect to login page for non-AJAX requests
return redirect(url_for('login'))
@app.route('/profile')
def profile():
cursor = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
# Check if it's an AJAX request
if request.headers.get('Content-Type') == 'application/json':
if 'loggedin' in session:
cursor.execute('SELECT * FROM users WHERE id = %s', [session['id']])
account = cursor.fetchone()
return jsonify({'message': 'Profile', 'account': dict(account)})
return jsonify({'message': 'User not logged in'})
# Redirect to login page for non-AJAX requests
return redirect(url_for('login'))
if __name__ == '__main__':
app.run(port=5000)
And this is my frontend login.js
// Login.js
import React, { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import './assets/css/Login.css';
import siginup from './assets/images/signup/Signuprobo.png';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const navigate = useNavigate();
const handleFormSubmit = async (e) => {
e.preventDefault();
try {
setLoading(true);
const response = await axios.post('http://localhost:5000/api/auth/login', {
username: username,
password: password,
},{ withCredentials: true });
localStorage.setItem('user-info', JSON.stringify(response.data));
navigate('/home');
} catch (error) {
setError('Incorrect username/password. Please try again.');
} finally {
setLoading(false);
}
};
const handleKeyDown = (e) => {
if (e.key === 'Enter') {
handleFormSubmit(e);
}
};
return (
<>
<header>
<div className="login-container">
<div className='flex-container' style={{ display: 'flex', alignItems:'flex-start' }}>
<div className='image-container'>
<h1 className=''>CASE <br /> MINISTER</h1>
<img src={siginup} alt="Login Image" />
</div>
<form onSubmit={handleFormSubmit}>
<div className='input-container'>
<h2 className='text-light'>Sign up</h2>
<p>Sign up now and gain access to exclusive content!</p>
<label htmlFor="">Email address</label>
<input
type="text"
placeholder='[email protected]'
onChange={(e) => setUsername(e.target.value)}
className='form-control'
autoComplete="off"
required
/>
<br />
<label htmlFor="">Password</label>
<input
type="password"
placeholder='password'
onChange={(e) => setPassword(e.target.value)}
onKeyDown={(e) => e.key === 'Enter' && Login()}
className='form-control'
autoComplete="new-password"
required
/>
<p style={{marginTop:'3px'}}>Forgot password? <a href='' style={{textDecoration:'none'}}>Reset password</a></p>
<button className='signup' type='submit'>Sign up</button>
<p style={{marginTop:'1rem'}}>By clicking on Sign up, you agree to our Terms of service and Privacy policy.</p>
<div className="or-container">
<span className="line"></span>
<span className="or-text">or</span>
<span className="line"></span>
</div>
{/* <GoogleLogin
onSuccess={credentialResponse => {
console.log(credentialResponse);
}}
onError={() => {
console.log('Login Failed');
}}
/>; */}
</div>
</form>
</div>
</div>
</header>
</>
);
}