Contenidos
Estructura del proyecto
1 2 3 4 5 6 7 8 9 10 11 12 |
proyecto/ ├── requirements.txt ├── vercel.json └── login/ ├── index.py └── templates/ ├── base.html ├── index.html ├── login.html └── signup.html └── key/ └── key.json |
Códigos
key.json (se obtiene de Firebase)
index.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
from flask import Flask, render_template, request, redirect, url_for, session import pyrebase import firebase_admin from firebase_admin import credentials, auth import os app = Flask(__name__) app.secret_key = os.environ.get('SECRET_KEY', 'JAKLDSJLFKAJSLKFJASDF') # usa variable de entorno si está disponible # Configuración de Firebase firebase_config = { "apiKey": "adsafsaf", "authDomain": "afafasdfsadf", "projectId": "fasfafasdf", "storageBucket": "afasfdasfasdf", "messagingSenderId": "2423424", "appId": "adfasfasfads", "databaseURL": "afdasfasfasdf" } firebase = pyrebase.initialize_app(firebase_config) auth_firebase = firebase.auth() # Configurar Firebase Admin SDK cred = credentials.Certificate('key/key.json') # Asegúrate de tener este archivo JSON firebase_admin.initialize_app(cred) @app.route('/') def index(): if 'user' in session: return render_template('index.html', user=session['user']) return redirect(url_for('login')) @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': email = request.form['email'] password = request.form['password'] try: user = auth_firebase.sign_in_with_email_and_password(email, password) session['user'] = user return redirect(url_for('index')) except: return 'Invalid credentials' return render_template('login.html') @app.route('/signup', methods=['GET', 'POST']) def signup(): if request.method == 'POST': email = request.form['email'] password = request.form['password'] try: user = auth_firebase.create_user_with_email_and_password(email, password) return redirect(url_for('login')) except: return 'Could not create account' return render_template('signup.html') @app.route('/logout') def logout(): session.pop('user', None) return redirect(url_for('login')) if __name__ == '__main__': app.run(debug=True) |
requirements.txt
1 2 3 4 5 6 |
pip autopep8 firebase-admin pyrebase4 Flask==3.0.3 setuptools |
vercel.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "builds": [ { "src": "login/index.py", "use": "@vercel/python" } ], "routes": [ { "src": "/(.*)", "dest": "login/index.py" } ] } |
templates
base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<!doctype html> <html lang="en"> <head> <!-- Required meta tags --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <!-- Bootstrap CSS --> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> <title>{% block title %}{% endblock %}</title> </head> <body> <div class="container"> {% block content %} {% endblock %} </div> <!-- Optional JavaScript --> <!-- jQuery first, then Popper.js, then Bootstrap JS --> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script> </body> </html> |
index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{% extends "base.html" %} {% block title %}Welcome{% endblock %} {% block content %} <div class="row justify-content-center mt-5"> <div class="col-md-6"> <div class="card"> <div class="card-body text-center"> <h5 class="card-title">Welcome, {{ user['email'] }}</h5> <a href="{{ url_for('logout') }}" class="btn btn-danger btn-block">Logout</a> </div> </div> </div> </div> {% endblock %} |
login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
{% extends "base.html" %} {% block title %}Login{% endblock %} {% block content %} <div class="row justify-content-center mt-5"> <div class="col-md-6"> <div class="card"> <div class="card-body"> <h5 class="card-title text-center">Login</h5> <form method="POST" action="{{ url_for('login') }}"> <div class="form-group"> <label for="email">Email address</label> <input type="email" class="form-control" id="email" name="email" required> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" class="form-control" id="password" name="password" required> </div> <button type="submit" class="btn btn-primary btn-block">Login</button> </form> <div class="text-center mt-3"> <a href="{{ url_for('signup') }}">Don't have an account? Sign up</a> </div> </div> </div> </div> </div> {% endblock %} |
signup.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
{% extends "base.html" %} {% block title %}Sign Up{% endblock %} {% block content %} <div class="row justify-content-center mt-5"> <div class="col-md-6"> <div class="card"> <div class="card-body"> <h5 class="card-title text-center">Sign Up</h5> <form method="POST" action="{{ url_for('signup') }}"> <div class="form-group"> <label for="email">Email address</label> <input type="email" class="form-control" id="email" name="email" required> </div> <div class="form-group"> <label for="password">Password</label> <input type="password" class="form-control" id="password" name="password" required> </div> <button type="submit" class="btn btn-primary btn-block">Sign Up</button> </form> <div class="text-center mt-3"> <a href="{{ url_for('login') }}">Already have an account? Login</a> </div> </div> </div> </div> </div> {% endblock %} |