Gostei bastante desse curso e gostaria de incrementar esse API para cadastrar novos usuários a partir da tela de login. Quero uma luz de como posso fazer isso.
Gostei bastante desse curso e gostaria de incrementar esse API para cadastrar novos usuários a partir da tela de login. Quero uma luz de como posso fazer isso.
Olá Flávio.
Essa vontade de sempre querer mais é que nos torna profissionais mais preparados para enfrentar as demandas que o mercado exige.
Vamos tentar te ajudar a achar o caminho.
Abaixo te explico passo a passo como estruturar isso, com exemplos de código e dicas de segurança.
Estrutura do Projeto
flask_app/
├── app.py
├── config.py
├── models.py
├── forms.py
├── routes.py
├── static/
│ └── uploads/
├── templates/
│ ├── base.html
│ ├── login.html
│ ├── register.html
│ ├── dashboard.html
│ └── crud.html
└── venv/
config.py)import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'chave-secreta-supersegura'
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://usuario:senha@localhost/nome_do_banco'
SQLALCHEMY_TRACK_MODIFICATIONS = False
UPLOAD_FOLDER = os.path.join(os.getcwd(), 'static/uploads')
MAX_CONTENT_LENGTH = 2 * 1024 * 1024 # 2MB
models.py)from flask_sqlalchemy import SQLAlchemy
from flask_bcrypt import Bcrypt
from datetime import datetime
db = SQLAlchemy()
bcrypt = Bcrypt()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
def set_password(self, password):
self.password_hash = bcrypt.generate_password_hash(password).decode('utf-8')
def check_password(self, password):
return bcrypt.check_password_hash(self.password_hash, password)
forms.py)from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, FileField
from wtforms.validators import DataRequired, Email, EqualTo, Length
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Senha', validators=[DataRequired()])
submit = SubmitField('Entrar')
class RegisterForm(FlaskForm):
username = StringField('Usuário', validators=[DataRequired(), Length(min=3, max=50)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Senha', validators=[DataRequired(), Length(min=6)])
confirm_password = PasswordField('Confirmar Senha', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Cadastrar')
class UploadForm(FlaskForm):
file = FileField('Selecionar arquivo', validators=[DataRequired()])
submit = SubmitField('Upload')
continua...
...
routes.py)import os
from flask import render_template, redirect, url_for, flash, request, session, current_app
from werkzeug.utils import secure_filename
from models import db, User
from forms import LoginForm, RegisterForm, UploadForm
def init_routes(app):
@app.route('/')
def index():
return render_template('login.html')
# --- LOGIN ---
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and user.check_password(form.password.data):
session['user_id'] = user.id
flash('Login realizado com sucesso!', 'success')
return redirect(url_for('dashboard'))
flash('Email ou senha inválidos', 'danger')
return render_template('login.html', form=form)
# --- REGISTRO DE NOVO USUÁRIO ---
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
flash('Cadastro realizado com sucesso! Faça login.', 'success')
return redirect(url_for('login'))
return render_template('register.html', form=form)
# --- DASHBOARD ---
@app.route('/dashboard')
def dashboard():
if 'user_id' not in session:
return redirect(url_for('login'))
return render_template('dashboard.html')
# --- UPLOAD DE ARQUIVO ---
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
form = UploadForm()
if form.validate_on_submit():
file = form.file.data
filename = secure_filename(file.filename)
file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
flash('Arquivo enviado com sucesso!', 'success')
return redirect(url_for('dashboard'))
return render_template('upload.html', form=form)
# --- LOGOUT ---
@app.route('/logout')
def logout():
session.pop('user_id', None)
flash('Você saiu da conta.', 'info')
return redirect(url_for('login'))
app.py)from flask import Flask
from config import Config
from models import db, bcrypt
from routes import init_routes
app = Flask(__name__)
app.config.from_object(Config)
db.init_app(app)
bcrypt.init_app(app)
with app.app_context():
db.create_all()
init_routes(app)
if __name__ == '__main__':
app.run(debug=True)
Dicas de Segurança
Flask-Bcrypt (como no exemplo).SECRET_KEY e credenciais do MySQL em .env.flask-login para gerenciamento de sessão mais seguro (opcional, mas recomendado).Você pode colocar um link na tela de login:
<p>Não tem conta? <a href="{{ url_for('register') }}">Cadastre-se aqui</a></p>
E isso levará o usuário diretamente para o formulário de registro, como implementado acima.
Vai fazendo ai e aproveita os conhecimentos que adquiriu no curso para complementar ou corrigir.
Se tiver alguma duvida pode perguntar.
Então é mão na massa e vai dando feedback com os resultados e experiencias.
Bons estudos.
Se quiser saber mais comente ai ...
Até...
Opa, muito obrigado pelo suporte. Assim que eu estiver com o pc em maos, tentarei. Obrigado novamente.