Flask Authentication
What is authentication in Flask?
Authentication in Flask refers to verifying the identity of users who are trying to access protected resources. It ensures that only authorized users can access certain routes or APIs. Authentication can be implemented using methods like session-based authentication, token-based authentication (e.g., JWT), or third-party OAuth providers.
What are the common methods of authentication in Flask?
Common methods of authentication in Flask include:
- Session-based Authentication: Uses Flask's built-in session handling to manage user authentication, where the server stores session information.
- Token-based Authentication: Typically uses JWT (JSON Web Tokens) to authenticate users by including the token in the request headers.
- Basic Authentication: Sends the username and password with each request (generally used in API requests).
- OAuth: Uses third-party providers (like Google or Facebook) to authenticate users.
How do you implement basic authentication in Flask?
Basic authentication can be implemented using the Flask-HTTPAuth extension. It sends the username and password with each request, and the server checks these credentials for every request.
Example of basic authentication:
from flask import Flask
from flask_httpauth import HTTPBasicAuth
app = Flask(__name__)
auth = HTTPBasicAuth()
users = {
"admin": "secret",
"user": "password"
}
@auth.get_password
def get_password(username):
if username in users:
return users[username]
return None
@app.route('/protected')
@auth.login_required
def protected_route():
return f"Hello, {auth.username()}!"
if __name__ == '__main__':
app.run(debug=True)
In this example, users must provide valid credentials to access the /protected route. The username and password are checked in each request.
How do you implement token-based authentication using JWT in Flask?
Token-based authentication using JWT (JSON Web Tokens) is a common approach where the server generates a token after the user logs in. The token is included in subsequent requests to authenticate the user.
Example of JWT authentication using Flask-JWT-Extended:
from flask import Flask, jsonify, request
from flask_jwt_extended import JWTManager, jwt_required, create_access_token, get_jwt_identity
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this to a random secret key
jwt = JWTManager(app)
users = {"user1": "password1"}
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
password = request.json.get('password')
if username not in users or users[username] != password:
return jsonify({'message': 'Invalid credentials'}), 401
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token), 200
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
current_user = get_jwt_identity()
return jsonify(logged_in_as=current_user), 200
if __name__ == '__main__':
app.run(debug=True)
In this example, users must log in using the /login route to receive a JWT token. The token is then included in the request headers for accessing the protected /protected route.
How do you send and verify JWT tokens in Flask?
In Flask, JWT tokens are sent in the request headers as Authorization: Bearer <token>. The token is generated using create_access_token() and verified in protected routes using the @jwt_required() decorator.
Example of sending a JWT token in headers:
curl -X GET http://localhost:5000/protected -H "Authorization: Bearer <your_token_here>"
In this example, the JWT token is included in the Authorization header, and the server verifies the token to grant access to the protected route.
How do you handle user registration and login in Flask?
User registration involves storing user credentials (typically hashed passwords) in a database, while login involves verifying these credentials during authentication. Here's how you might handle both in Flask:
Example of user registration and login:
from flask import Flask, jsonify, request
from werkzeug.security import generate_password_hash, check_password_hash
from flask_jwt_extended import JWTManager, create_access_token, jwt_required
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'super-secret'
jwt = JWTManager(app)
users = {}
@app.route('/register', methods=['POST'])
def register():
data = request.get_json()
username = data['username']
password = data['password']
if username in users:
return jsonify({'message': 'User already exists'}), 400
users[username] = generate_password_hash(password)
return jsonify({'message': 'User registered successfully'}), 201
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
username = data['username']
password = data['password']
if username not in users or not check_password_hash(users[username], password):
return jsonify({'message': 'Invalid credentials'}), 401
access_token = create_access_token(identity=username)
return jsonify(access_token=access_token), 200
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected():
return jsonify({'message': 'Access granted to protected route'}), 200
if __name__ == '__main__':
app.run(debug=True)
In this example, users can register using the /register route, and their passwords are securely hashed. The /login route checks the credentials and returns a JWT token for authenticated users.
How do you implement OAuth authentication in Flask?
OAuth allows users to authenticate through third-party providers like Google, Facebook, or GitHub. Flask can integrate OAuth using the Flask-Dance or Authlib extensions, which handle the OAuth flow.
Example of Google OAuth using Flask-Dance:
from flask import Flask, redirect, url_for
from flask_dance.contrib.google import make_google_blueprint, google
app = Flask(__name__)
app.config['SECRET_KEY'] = 'supersecret'
google_bp = make_google_blueprint(client_id="your_client_id", client_secret="your_client_secret", redirect_to="google_login")
app.register_blueprint(google_bp, url_prefix="/login")
@app.route('/')
def index():
return "Welcome to the app!"
@app.route('/google_login')
def google_login():
if not google.authorized:
return redirect(url_for('google.login'))
resp = google.get("/plus/v1/people/me")
return f"You are logged in as {resp.json()['displayName']}"
if __name__ == '__main__':
app.run(debug=True)
In this example, the user can log in via Google OAuth. The Flask-Dance blueprint handles the OAuth flow, and the user's Google profile information is retrieved after successful authentication.
How do you protect routes in Flask using authentication?
In Flask, you can protect routes by requiring authentication before users can access them. This is typically done using decorators like @jwt_required() (for token-based authentication) or @auth.login_required (for basic authentication).
Example of protecting a route using JWT authentication:
@app.route('/protected', methods=['GET'])
@jwt_required()
def protected_route():
return jsonify({'message': 'This is a protected route'})
In this example, the @jwt_required() decorator ensures that only users with a valid JWT token can access the /protected route.
How do you handle password hashing in Flask?
Password hashing in Flask is typically done using the werkzeug.security library, which provides functions like generate_password_hash() and check_password_hash(). Storing hashed passwords is crucial for security as it protects user passwords even if the database is compromised.
Example of password hashing:
from werkzeug.security import generate_password_hash, check_password_hash
hashed_password = generate_password_hash("mypassword")
print(check_password_hash(hashed_password, "mypassword")) # Returns True
In this example, the password is hashed using generate_password_hash(), and check_password_hash() is used to verify the password during login.
How do you handle logout in token-based authentication?
In token-based authentication, logging out is generally handled by blacklisting the token or allowing it to expire. This can be done by storing the tokens in a blacklist and checking whether the token is valid before processing each request.
Example of token blacklisting using Flask-JWT-Extended:
from flask_jwt_extended import JWTManager, jwt_required, get_jwt, create_access_token
from flask import Flask, jsonify
app = Flask(__name__)
app.config['JWT_SECRET_KEY'] = 'super-secret'
app.config['JWT_BLACKLIST_ENABLED'] = True
jwt = JWTManager(app)
blacklist = set()
@jwt.token_in_blocklist_loader
def check_if_token_in_blacklist(jwt_header, jwt_payload):
jti = jwt_payload['jti']
return jti in blacklist
@app.route('/logout', methods=['POST'])
@jwt_required()
def logout():
jti = get_jwt()['jti']
blacklist.add(jti)
return jsonify({'message': 'Successfully logged out'}), 200
if __name__ == '__main__':
app.run(debug=True)
In this example, the token's unique identifier (JTI) is added to a blacklist during logout. The check_if_token_in_blacklist function ensures that blacklisted tokens cannot be used to access protected routes.