Skip to content

Nebula - 2.2.0

Choose a tag to compare

@VxidDev VxidDev released this 21 Mar 10:06

Nebula Session Management Feature - Release Notes

New feature just arrived! Now you can easily manage user sessions and authentication in your Nebula applications. This update introduces a secure, cookie-based session management system that integrates seamlessly with both standard HTTP routes and Socket.IO event handlers.

Key features include:

  • Cookie-Based Sessions: Securely store session data on the client using HMAC-signed cookies.
  • User Authentication: A simple API to log users in, log them out, and check their authentication status.
  • Route Protection: A decorator to easily protect routes and require user login.
  • WebSocket Integration: Authenticate users for your real-time WebSocket connections.
  • Flexible User Model: Integrates with your existing user model via a simple mixin.

How to Use

1. Enable Sessions

First, enable session management by calling app.setup_sessions() with a secret key. This is crucial for signing the session cookies securely.

from nebula import Nebula

app = Nebula(__file__, "0.0.0.0", 5000)
app.init_all()

# Enable sessions with a secret key
app.setup_sessions(secret_key="a-super-secret-key-that-you-should-change")

2. Create a User Model

Your user class should inherit from UserMixin to be compatible with Nebula's authentication system. This mixin provides default properties like is_authenticated.

from nebula import UserMixin

class User(UserMixin):
    def __init__(self, user_id, username):
        self.id = user_id
        self.username = username

3. Implement a User Loader

Nebula needs a way to load a user object from the ID stored in the session. Create a function for this and decorate it with @app.user_loader.

# A dummy user database
USERS = {"1": User("1", "alice"), "2": User("2", "bob")}

@app.user_loader
def load_user(user_id: str):
    return USERS.get(user_id)

4. Log Users In and Out

Use the login_user and logout_user functions to manage user authentication state.

from nebula import login_user, logout_user, current_user
from werkzeug.utils import redirect

@app.route("/login", methods=["POST"])
def login():
    # In a real app, you'd validate a username and password
    user = USERS.get("1") # Example: logging in user "alice"
    if user:
        login_user(user)
    return redirect("/dashboard")

@app.route("/logout")
def logout():
    logout_user()
    return redirect("/login")

5. Protect Routes

Use the @login_required() decorator to protect routes that require authentication. Unauthenticated users will be redirected to the specified login page.

from nebula import login_required

@app.route("/dashboard")
@login_required(redirect_to="/login")
def dashboard():
    return f"Welcome, {current_user.username}!"

6. Authenticate WebSocket Connections

You can also authenticate users for your Socket.IO connections. Use app.get_session_from_environ() in your on_connect handler to access the session and verify the user.

@app.on_connect()
def on_connect(sid, environ):
    session = app.get_session_from_environ(environ)
    user_id = session.get("_user_id")

    if not user_id:
        return False  # Reject connection

    user = load_user(user_id)
    if not user:
        return False # Reject connection

    print(f"{user.username} connected to WebSocket")
    # You can now associate the user with the connection (sid)

New Example: Authenticated Chat

To see this feature in action, check out the new chat_auth.py example in the examples/ directory. It demonstrates how to build a real-time chat application with session-based authentication.