Open In App

Python Pyramid – Authentication

Last Updated : 08 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In this article, we will delve into the concept of user authentication within the context of Python Pyramid. Additionally, we will illustrate authentication through a practical example where we establish a login and logout system along with a signup page. In this scenario, users are required to sign up before being able to log in.

What is Python Pyramid – Login with Authentication?

Python Pyramid is a web framework that helps developers build web applications in Python, providing tools for creating and organizing these applications. “Login with Authentication” in the context of Python Pyramid means establishing a system where users can log in with a username and password, ensuring their identity is valid. It’s like having a secret key to access a secure place, allowing only authorized users to enter specific parts of a website. Implementing this involves creating a mechanism to check user credentials, and granting access to protected areas when the provided information is correct.

When to use Python Pyramid – Login with Authentication

You might choose to use Python Pyramid for implementing “Login with Authentication” in a web application when you need a robust and flexible framework to handle the complexities of user authentication. Python Pyramid provides a solid structure for building web applications, making it suitable for projects of various sizes and complexities.

If your web application requires user registration, login functionality, and secure access to certain parts of the site based on user roles, Python Pyramid’s capabilities for handling authentication can be beneficial. Its modular design and support for customization allow you to implement authentication mechanisms tailored to your specific requirements. Additionally, if you are working on a project that demands scalability and maintainability, Python Pyramid’s flexibility can be advantageous in managing user authentication features as your application grows.

Python Pyramid – Login/Signup App

Here, we will utilize Python Pyramid to develop a login and signup page. To create these pages, follow the steps outlined below.

Step 1: Create the virtual environment

Using the below command create virutal environment

python -m venv env 
.\env\Scripts\activate.ps1

File Strcuture

Step 2: Implement the Logic

app.py : This Python Pyramid application demonstrates a simple web system with login, signup, dashboard, and logout functionality. It uses session management to store user credentials, and the views are rendered using Jinja2 templates. The signup process includes password validation and checks for duplicate usernames, while the login process verifies user credentials and provides flash messages for user feedback. The dashboard and logout routes render their respective templates, and the server runs on port 6543. Note: Additional template files and project structure are assumed for proper execution.

Python3




from wsgiref.simple_server import make_server
from pyramid.config import Configurator
from pyramid.renderers import render_to_response
from pyramid.view import view_config
from pyramid.session import SignedCookieSessionFactory
 
my_session = SignedCookieSessionFactory("mySession")
myList = []
 
@view_config(route_name="login", renderer="index.html")
def login(request):
    request.session["credentials"] = myList # Storing Credentials in Session
 
    if request.method == "POST":
        username = request.POST["username"]
        password = request.POST["password"]
 
        for i in request.session["credentials"]:
            if i[0] == username and i[1] == password:
                request.session["username"] = username
                request.session["password"] = password
                request.session["logged_in"] = True
                return render_to_response(
                    "./views/dashboard.html", {"error": "Success!"}, request=request
                )
 
        # For Flash Message Provided by Session
        request.session.pop("username", None)
        request.session.pop("password", None)
        request.session["logged_in"] = False
 
        request.session.flash("Please fill in all fields properly!")
        return render_to_response(
            "./views/index.html",
            {"error": "Please fill in all fields properly!"},
            request=request,
        )
    else:
        return render_to_response("./views/index.html", {}, request=request)
     
 
@view_config(route_name="signup", renderer="signup.html")
def signup(request):
    if request.method == "POST":
        username = request.POST["username"]
        password1 = request.POST["password1"]
        password2 = request.POST["password2"]
        if password1 == password2:
            flag=0
            for i in myList:
                if i[0] == username:
                    flag=1
                    break
            if flag:
                request.session.flash("Username already exists!")
                return render_to_response(
                    "./views/signup.html",
                    {"error": "Username already exists!"},
                    request=request,
                )
            else:
                myList.append([username, password1])
                request.session["credentials"] = myList
                request.session["username"] = username
                request.session["password"] = password1
                request.session["logged_in"] = True
                 
                return render_to_response(
                    "./views/dashboard.html", {"error": "Success!"}, request=request
                )
        else:
            request.session.flash("Passwords do not match!")
            return render_to_response(
                "./views/signup.html",
                {"error": "Passwords do not match!"},
                request=request,
            )
    else:
        return render_to_response("./views/signup.html", {}, request=request)
 
 
@view_config(route_name="dashboard", renderer="dashboard.html")
def dashboard(request):
    return render_to_response("./views/dashboard.html", {}, request=request)
 
@view_config(route_name="logout", renderer="logout.html")
def logout(request):
    request.session.pop("username", None)
    request.session.pop("password", None)
    request.session["logged_in"] = False
 
    return render_to_response(
        "./views/logout.html",
        {"error": "You have been logged out!"},
        request=request
    )
 
 
if __name__ == "__main__":
    with Configurator() as config:
        # Initialize Session Factory
        config.set_session_factory(my_session)
 
        # Add Jinja2 Template Renderer
        config.include("pyramid_jinja2")
        config.add_jinja2_renderer(".html")
 
        # Add Routes and Views
        config.add_route("login", "/")
        config.add_view(login, route_name="login")
 
        config.add_route("dashboard", "/dashboard.html")
        config.add_view(dashboard, route_name="dashboard")
 
        config.add_route("logout", "/logout.html")
        config.add_view(logout, route_name="logout")
 
        config.add_route("signup", "/signup.html")
        config.add_view(signup, route_name="signup")
 
        config.scan("flash")
 
        app = config.make_wsgi_app()
 
    server = make_server("0.0.0.0", 6543, app)
    server.serve_forever()


Step 3: Creating GUI

index.html : This HTML code represents a login page template in a Pyramid web application using Jinja2. It includes Bootstrap for styling. The page displays flash messages if available, providing user feedback. The login form takes input for username and password, with a link to the signup page. Bootstrap styling is used for form elements and buttons, enhancing the visual appeal and responsiveness of the login interface.

HTML




<!DOCTYPE html>
<html lang="en">
<include package="pyramid_jinja2"/>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
          rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
          crossorigin="anonymous">
</head>
<body>
    <br>
    <div>
        {% if request.session.peek_flash()%}
            <div id="flash" class="container jumbotron">
                {% for message in request.session.pop_flash() %}
                    <center><h1>{{ message }}</h1></center>
                {% endfor %}
            </div>
        {% endif %}
    </div>
    <br>
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3 mt-5">
                <h1>Login</h1>
                <form action="" method="POST">
                    <div class="mb-3">
                        <label for="username" class="form-label">Username</label>
                        <input type="text" name="username" id="username" class="form-control"
                               placeholder="Username" aria-describedby="helpId">
                    </div>
                    <div class="mb-3">
                        <label for="password" class="form-label">Password</label>
                        <input type="text" name="password" id="password" class="form-control"
                               placeholder="Password" aria-describedby="helpId">
                    </div>
                    <button type="submit" class="btn btn-primary">Login</button>
                </form>
 
                <!-- Sign Up! -->
                <br>
                <a href="signup.html">
                    <button type="button" class="btn btn-primary">Sign Up!</button>
                </a>
            </div>
        </div>
    </div>
</body>
</html>


signup.html : This HTML code represents a signup page template in a Pyramid web application using Jinja2. Bootstrap is included for styling. The page displays flash messages for user feedback. The signup form takes input for username, password, and password confirmation. Bootstrap styling is applied to form elements and buttons for a visually appealing and responsive signup interface

HTML




<!DOCTYPE html>
<html lang="en">
<include package="pyramid_jinja2"/>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sign Up</title>
          rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
          crossorigin="anonymous">
</head>
<body>
    <br>
    <div>
        {% if request.session.peek_flash()%}
            <div id="flash" class="container jumbotron">
                {% for message in request.session.pop_flash() %}
                    <center><h1>{{ message }}</h1></center>
                {% endfor %}
            </div>
        {% endif %}
    </div>
    <br>
    <div class="container">
        <div class="row">
            <div class="col-md-6 offset-md-3 mt-5">
                <h1>Sign Up</h1>
                <form action="" method="POST">
                    <div class="mb-3">
                        <label for="username" class="form-label">Username</label>
                        <input type="text" name="username" id="username" class="form-control" placeholder="Username" aria-describedby="helpId">
                    </div>
                    <div class="mb-3">
                        <label for="password" class="form-label">Password</label>
                        <input type="text" name="password1" id="password1" class="form-control" placeholder="Password" aria-describedby="helpId">
                    </div>
                    <div class="mb-3">
                        <label for="password" class="form-label">Password</label>
                        <input type="text" name="password2" id="password2" class="form-control" placeholder="Retype Password" aria-describedby="helpId">
                    </div>
                    <button type="submit" class="btn btn-primary">Sign Up</button>
                </form>
                <!-- Login -->
                <br>
                <a href="/">
                    <button type="button" class="btn btn-primary">Login</button>
                </a>
            </div>
        </div>
    </div>
</body>
</html>


logout.html : This HTML code represents a logout page template in a Pyramid web application using Jinja2. Bootstrap is included for styling. The page displays a message notifying the user that they have been logged out. A link to the login page is provided for users to navigate back to the login screen. The centered layout and minimalistic design contribute to a clear and concise logout interface.

HTML




<!DOCTYPE html>
<html lang="en">
<include package="pyramid_jinja2"/>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Logout</title>
          rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
          crossorigin="anonymous">
</head>
<body>
    <br>
    <center>
        <h3>You have been logged out!</h3>
        <br>
        <a href="/">Login</a>
    </center>
</body>
</html>


dashboard.html : This HTML code represents a dashboard page template in a Pyramid web application using Jinja2. Bootstrap is included for styling. The page includes a heading “Dashboard” and checks if the user is logged in. If logged in, it displays a personalized welcome message with the username. If not logged in, it redirects the user to the login page.

HTML




<!DOCTYPE html>
<html lang="en">
<include package="pyramid_jinja2"/>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard</title>
          rel="stylesheet"
          integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
          crossorigin="anonymous">
</head>
<body>
    <br>
    <center>
        <h2>Dashboard</h2>
        {% if request.session.get('logged_in')  %}
            <h3>Welcome! {{ request.session['username'] }}</h3>
        {% else %}
            <script>
                window.location.href = "/";
            </script>
        {% endif %}
        <br>
        <a href="/logout.html">Logout</a>
    </center>
</body>
</html>


Step 5: Run the Server

python .\app.py

Output:

https:\\localhost:6543

signup-

signup.html

first-login-

login.html

logout-

Video Demonstration

Conclusion

In conclusion, Python Pyramid Sessions provide a powerful mechanism for managing user interactions and state in web applications. Sessions facilitate the storage and retrieval of data, enabling features such as user authentication, personalization, and data persistence across multiple requests. The built-in session factory implementation in Pyramid, though convenient, comes with considerations such as non-encrypted session information and size limitations. Developers should carefully assess security and data requirements when leveraging Pyramid Sessions.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads