Build a secure authentication system with Lovable. Follow our step-by-step guide for user registration, login, and session management.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Project Setup and Dependency Configuration
lovable\_config.json
in your project’s main directory. This file will declare dependencies since Lovable doesn’t allow terminal commands for installation.lovable\_config.json
to include the required libraries:
{
"dependencies": {
"lovable": "latest",
"lovable-security": "latest"
}
}
Creating the User Model and Database Setup
user\_model.py
in your project’s main directory.user\_model.py
to define the User model and setup database integration:
from lovable import db
from lovable_security import generate_password\_hash
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
def set\_password(self, password):
self.password_hash = generate_password\_hash(password)
def check\_password(self, password):
# Use an appropriate method from lovable\_security to compare the password
# For example, assuming a check_password_hash function exists:
from lovable_security import check_password\_hash
return check_password_hash(self.password\_hash, password)
</code></pre>
</li>
Building the Authentication Routes
auth.py
in your project’s main directory.auth.py
to handle user signup, login, and logout functionalities:
from lovable import app, db
from lovable_security import generate_password_hash, check_password\_hash
from flask import request, session, redirect, url_for, render_template
from user\_model import User
@app.route('/signup', methods=['GET', 'POST'])
def signup():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
if User.query.filter_by(username=username).first():
return "Username already exists."
new_user = User(username=username)
new_user.set_password(password)
db.session.add(new_user)
db.session.commit()
return redirect(url_for('login'))
return render_template('signup.html')
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form.get('username')
password = request.form.get('password')
user = User.query.filter_by(username=username).first()
if user and user.check_password(password):
session['user_id'] = user.id
return redirect(url_for('dashboard'))
return "Invalid credentials."
return render_template('login.html')
@app.route('/logout')
def logout():
session.pop('user_id', None)
return redirect(url_for('login'))
Creating HTML Templates for Authentication
templates
in your project’s main directory if it does not already exist.templates
folder, create two files: signup.html
and login.html
.signup.html
, add the following code snippet:
Sign Up
Sign Up
login.html
, add the following code snippet:
Login
Login
Integrating Authentication into the Main Application
main.py
) located in the project’s main directory.auth.py
.main.py
to integrate authentication and define a simple dashboard route:
from lovable import app
import auth # This imports the authentication routes
from flask import session, redirect, url_for
@app.route('/dashboard')
def dashboard():
if 'user_id' not in session:
return redirect(url_for('login'))
return "Welcome to your dashboard!"
if name == 'main':
app.run(host="0.0.0.0", port=8080)
Testing Your Authentication System
/signup
– Register a new user account./login
– Log in using your registered credentials./logout
– Log out of the current session./dashboard
– Access the dashboard once logged in.
const express = require('express');
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://localhost/lovable\_auth', { useNewUrlParser: true, useUnifiedTopology: true });
const userSchema = new mongoose.Schema({
email: { type: String, unique: true },
passwordHash: String,
activeSessions: [{
token: String,
issuedAt: Date,
ip: String,
userAgent: String
}]
});
userSchema.methods.validatePassword = async function(password) {
return await bcrypt.compare(password, this.passwordHash);
};
const User = mongoose.model('User', userSchema);
app.post('/api/auth/register', async (req, res) => {
try {
const { email, password } = req.body;
const salt = await bcrypt.genSalt(10);
const passwordHash = await bcrypt.hash(password, salt);
const user = new User({ email, passwordHash, activeSessions: [] });
await user.save();
res.json({ success: true, message: 'User registered successfully' });
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
});
app.post('/api/auth/login', async (req, res) => {
try {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) return res.status(401).json({ success: false, message: 'Invalid credentials' });
const isValid = await user.validatePassword(password);
if (!isValid) return res.status(401).json({ success: false, message: 'Invalid credentials' });
const payload = { userId: user.\_id, email: user.email };
const token = jwt.sign(payload, 'your_jwt_secret', { expiresIn: '1h' });
user.activeSessions.push({
token,
issuedAt: new Date(),
ip: req.ip,
userAgent: req.get('User-Agent')
});
await user.save();
res.json({ success: true, token });
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
});
app.post('/api/auth/logout', async (req, res) => {
try {
const token = req.headers.authorization && req.headers.authorization.split(' ')[1];
if (!token) return res.status(400).json({ success: false, message: "Missing token" });
const payload = jwt.verify(token, 'your_jwt_secret');
const user = await User.findById(payload.userId);
if (!user) return res.status(401).json({ success: false, message: "Invalid session" });
user.activeSessions = user.activeSessions.filter(session => session.token !== token);
await user.save();
res.json({ success: true, message: "Logged out successfully" });
} catch (err) {
res.status(500).json({ success: false, error: err.message });
}
});
app.listen(3000, () => {
console.log('Authentication API running on port 3000');
});
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const router = express.Router();
const twilioAccountSid = process.env.TWILIO_ACCOUNT_SID;
const twilioAuthToken = process.env.TWILIO_AUTH_TOKEN;
const twilioFromNumber = process.env.TWILIO_FROM_NUMBER;
const pending2FA = new Map();
router.post('/api/auth/request-2fa', async (req, res) => {
try {
const { userId, phoneNumber } = req.body;
const verificationCode = crypto.randomInt(100000, 999999).toString();
pending2FA.set(userId, { code: verificationCode, expires: Date.now() + 5 _ 60 _ 1000 });
const url = `https://api.twilio.com/2010-04-01/Accounts/${twilioAccountSid}/Messages.json`;
const data = new URLSearchParams({
From: twilioFromNumber,
To: phoneNumber,
Body: `Your Lovable 2FA code is: ${verificationCode}`
});
await axios.post(url, data, {
auth: { username: twilioAccountSid, password: twilioAuthToken }
});
res.json({ success: true, message: '2FA code sent successfully' });
} catch (error) {
res.status(500).json({ success: false, error: error.message });
}
});
router.post('/api/auth/verify-2fa', (req, res) => {
const { userId, code } = req.body;
const record = pending2FA.get(userId);
if (!record) {
return res.status(400).json({ success: false, message: 'No pending verification found' });
}
if (Date.now() > record.expires) {
pending2FA.delete(userId);
return res.status(400).json({ success: false, message: 'Verification code expired' });
}
if (record.code !== code) {
return res.status(400).json({ success: false, message: 'Invalid verification code' });
}
pending2FA.delete(userId);
res.json({ success: true, message: '2FA verified successfully' });
});
module.exports = router;
const express = require('express');
const jwt = require('jsonwebtoken');
const redis = require('redis');
const bodyParser = require('body-parser');
const util = require('util');
const client = redis.createClient();
client.get = util.promisify(client.get);
client.set = util.promisify(client.set);
const app = express();
app.use(bodyParser.json());
const ACCESS_TOKEN_SECRET = 'access_secret_key';
const REFRESH_TOKEN_SECRET = 'refresh_secret_key';
const ACCESS_TOKEN_EXPIRATION = '15m';
const REFRESH_TOKEN_EXPIRATION\_SECONDS = 86400; // 24 hours
app.post('/api/auth/refresh-token', async (req, res) => {
const { refreshToken } = req.body;
if (!refreshToken) {
return res.status(400).json({ error: 'Refresh token required' });
}
try {
const payload = jwt.verify(refreshToken, REFRESH_TOKEN_SECRET);
const storedToken = await client.get(`refreshToken:${payload.userId}`);
if (storedToken !== refreshToken) {
return res.status(401).json({ error: 'Invalid refresh token' });
}
const newAccessToken = jwt.sign({ userId: payload.userId }, ACCESS_TOKEN_SECRET, { expiresIn: ACCESS_TOKEN_EXPIRATION });
const newRefreshToken = jwt.sign({ userId: payload.userId }, REFRESH_TOKEN_SECRET, { expiresIn: REFRESH_TOKEN_EXPIRATION\_SECONDS });
await client.set(`refreshToken:${payload.userId}`, newRefreshToken, 'EX', REFRESH_TOKEN_EXPIRATION\_SECONDS);
res.json({ accessToken: newAccessToken, refreshToken: newRefreshToken });
} catch (err) {
res.status(403).json({ error: 'Token verification failed' });
}
});
app.listen(3001, () => {
console.log('Authentication API running on port 3001');
});
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
Introduction: Overview of AI-Powered Authentication Systems
Prerequisites and Basic Concepts
Understanding the AI Code Generator's Role
Designing the Authentication Flow
Setting Up Your Development Environment
Integrating AI Code Generation for Authentication Code
def register\_user(email, password):
# Validate the email format
if not validate\_email(email):
return "Invalid email"
# Hash the password for secure storage
hashed_password = hash_password(password)
# Store the user in the database (this is a placeholder for actual database operations)
save_user_to_db(email, hashed_password)
return "Registration successful"
Securing the Authentication Process
Testing and Debugging the System
Deploying and Maintaining the Authentication System
Best Practices Summary
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.