In this in-depth tutorial, we’ll walk through the process of building a robust REST API using Flask, MongoDB, and JWT authentication. This guide is designed for developers with basic Python knowledge and assumes you have Python and an IDE installed.
Setting up Flask
Flask is a lightweight and flexible Python web framework that’s perfect for building APIs. Let’s start by installing Flask
pip install flask
Now, create a new file named app.py
and set up a basic Flask application
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/')
def hello():
return "Welcome to our Flask API!"
if __name__ == '__main__':
app.run(debug=True)
This creates a simple Flask app with a single route. The debug=True
parameter enables automatic reloading when you make changes to your code, which is helpful during development.
Understanding RESTful Principles
Before we continue building our API, let’s review some key RESTful principles
Use HTTP methods appropriately
- GET: Retrieve resources
- POST: Create new resources
- PUT: Update existing resources
- DELETE: Remove resources
Use meaningful endpoints
- GET /users: Retrieve all users
- POST /users: Create a new user
- GET /users/123: Retrieve user with ID 123
- PUT /users/123: Update user with ID 123
- DELETE /users/123: Delete user with ID 123
Use appropriate HTTP status codes
- 200: OK
- 201: Created
- 204: No Content
- 400: Bad Request
- 401: Unauthorized
- 404: Not Found
- 500: Internal Server Error
Integrating MongoDB
MongoDB is a popular NoSQL database that stores data in flexible, JSON-like documents. Let’s set it up
- Sign up at https://www.mongodb.com/cloud/atlas and create a free cluster.
- Set up database access and network access as guided by MongoDB Atlas.
- Once your cluster is ready, click “Connect” and choose “Connect your application”. Copy the connection string.
- Now, let’s install PyMongo to interact with MongoDB
pip install pymongo
Add MongoDB configuration to your app.py
from pymongo import MongoClient
# Replace with your actual connection string
client = MongoClient('your_mongodb_connection_string')
db = client['your_database_name']
users_collection = db['users']
Implementing User Authentication with JWT
JWT (JSON Web Tokens) provide a secure way to authenticate users in your API. Let’s set it up
First, install the necessary packages
pip install flask-jwt-extended passlib
Now, update your app.py
with JWT configuration and user authentication endpoints
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from passlib.hash import pbkdf2_sha256 as sha256
app.config['JWT_SECRET_KEY'] = 'your-secret-key' # Change this!
jwt = JWTManager(app)
@app.route('/register', methods=['POST'])
def register():
new_user = request.json
if users_collection.find_one({'username': new_user['username']}):
return jsonify({'message': 'Username already exists'}), 409
new_user['password'] = sha256.hash(new_user['password'])
users_collection.insert_one(new_user)
return jsonify({'message': 'User registered successfully'}), 201
@app.route('/login', methods=['POST'])
def login():
login_details = request.json
user = users_collection.find_one({'username': login_details['username']})
if user and sha256.verify(login_details['password'], user['password']):
access_token = create_access_token(identity=user['username'])
return jsonify({'access_token': access_token}), 200
return jsonify({'message': 'Invalid username or password'}), 401
Creating Secure API Endpoints
Now that we have user authentication set up, let’s create a secure endpoint for user profiles
@app.route('/profile', methods=['GET'])
@jwt_required()
def profile():
current_user = get_jwt_identity()
user = users_collection.find_one({'username': current_user}, {'_id': 0, 'password': 0})
if not user:
return jsonify({'message': 'User not found'}), 404
return jsonify(user), 200
This endpoint is protected by the @jwt_required()
decorator, ensuring that only authenticated users can access it
Full Code
Here’s the complete app.py
combining all the elements we’ve discussed
from flask import Flask, request, jsonify
from flask_jwt_extended import JWTManager, create_access_token, jwt_required, get_jwt_identity
from pymongo import MongoClient
from passlib.hash import pbkdf2_sha256 as sha256
app = Flask(__name__)
# MongoDB setup
client = MongoClient('your_mongodb_connection_string')
db = client['your_database_name']
users_collection = db['users']
# JWT setup
app.config['JWT_SECRET_KEY'] = 'your-secret-key' # Change this!
jwt = JWTManager(app)
@app.route('/')
def hello():
return "Welcome to our Flask API!"
@app.route('/register', methods=['POST'])
def register():
new_user = request.json
if users_collection.find_one({'username': new_user['username']}):
return jsonify({'message': 'Username already exists'}), 409
new_user['password'] = sha256.hash(new_user['password'])
users_collection.insert_one(new_user)
return jsonify({'message': 'User registered successfully'}), 201
@app.route('/login', methods=['POST'])
def login():
login_details = request.json
user = users_collection.find_one({'username': login_details['username']})
if user and sha256.verify(login_details['password'], user['password']):
access_token = create_access_token(identity=user['username'])
return jsonify({'access_token': access_token}), 200
return jsonify({'message': 'Invalid username or password'}), 401
@app.route('/profile', methods=['GET'])
@jwt_required()
def profile():
current_user = get_jwt_identity()
user = users_collection.find_one({'username': current_user}, {'_id': 0, 'password': 0})
if not user:
return jsonify({'message': 'User not found'}), 404
return jsonify(user), 200
if __name__ == '__main__':
app.run(debug=True)
Conclusion
In this comprehensive tutorial, we’ve built a Flask REST API with MongoDB integration and JWT authentication. This provides a solid foundation for building secure and scalable web applications.
Some key takeaways
- Flask provides a flexible framework for building APIs.
- MongoDB offers a scalable, document-based database solution.
- JWT authentication secures your API endpoints.
- RESTful principles guide the structure and behavior of your API.
As you continue developing, consider implementing additional features such as
- More comprehensive error handling
- Input validation
- Rate limiting to prevent abuse
- Refresh tokens for enhanced security
- Additional CRUD operations for user data
Remember to always keep your secret keys secure and never share them publicly. Regularly update your dependencies to ensure you’re using the latest security patches.
Happy coding, and enjoy building your Flask APIs!