Expiring Links Tutorial: Python Flask One-Time Link Generator

One time links are essential where users want to share resources with co-worker or friend’s effortlessly but at the same time restrict other from access.

Its works best because the link automatically inactive if some one go to the link for the first time. That means the same link will not work for the second time. or for other user.

Also we can set time so if no one enters the link it will automatically inactive after the specific time.

Now begin our program

  1. first the user will generate the link. and share..
  2. Other user will go to link and get access.
  3. the link(token) will be deleted from the active token list so it will not work anymore
  4. If no one access the link it will automatically remove from the shared link after specific time.

Generate link

we will use python secrets library to generate the unique token for the link

def generate_token():
    return secrets.token_urlsafe(16)

this is existing users list.( its example for the users who have account)


main_user_ids = ['user1', 'user2', 'user3']

So this users will be able to create the link for friends and co-workers

we will store the active token in python dictionary right now. For real world application you can use database like sql, mongodb or whatever you want

active_tokens = {}

This is code what the main users will get in the browser. You can use render template and place hte index.html in the template folder. but for simplicity we applied it directly.

@app.route('/', methods=['GET'])
def index():
    #return render_template('index.html')
    return """
    <!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Generate Connection Link</title>
</head>
<body>
    <h1>Generate Connection Link</h1>
    <form action="/generate_link" method="post">
        <label for="user_id">Enter User ID:</label><br>
        <input type="text" id="user_id" name="user_id"><br><br>
        <input type="submit" value="Generate Link">
    </form>
</body>
</html>
"""

Here the main users will enter the user name and generate the link on behalf of them

This is the second part of the code where generate the key from the previous code form action generate link

from datetime import datetime, timedelta
TOKEN_EXPIRY_DURATION = timedelta(hours=1)

# Route to generate a connection link
@app.route('/generate_link', methods=['POST'])
def generate_link():
    user_id = request.form.get('user_id') if request.form.get('user_id') in main_user_ids else None
    if user_id:
        token = generate_token()
        expiry_time = datetime.now() + TOKEN_EXPIRY_DURATION
        active_tokens[token] = (user_id, expiry_time)
        return f"Generated link from user {user_id}: <a href='/connect/{token}'>Click here to connect</a>"  # Return the generated token to the user
    else:
        return "Invalid user ID"

Here in the server side get the user name from the user . if user name exists then create an unique token and link on behalf of the user

Next part Verify the users access



# Route to handle the connection link
@app.route('/connect/<token>', methods=['GET'])
def connect(token):
    if token in active_tokens:
        user_id, expiry_time = active_tokens[token]
        if datetime.now() < expiry_time:
            # Connection successful, do something with the user_id
            del active_tokens[token]  # Mark the token as used
            return f"You have grant access by {user_id}"
        else:
            return "Token expired"
    else:
        return "Invalid token"

In this part the link is received from the user and verify if that exist. if exist and have expiration time . It grant the permission to that user and delete link(token) from the active tokens.

The complete code


from flask import Flask, request, redirect, url_for, render_template
from datetime import datetime, timedelta
import secrets

app = Flask(__name__)

# Active tokens and their expiry times
active_tokens = {}

# Duration for the token to remain valid (e.g., 1 hour)
TOKEN_EXPIRY_DURATION = timedelta(hours=1)

# Main user IDs
main_user_ids = ['user1', 'user2', 'user3']

# Function to generate a unique token
def generate_token():
    return secrets.token_urlsafe(16)

# Route to render the form
@app.route('/', methods=['GET'])
def index():
    #return render_template('index.html')
    return """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Generate Connection Link</title>
</head>
<body>
    <h1>Generate Connection Link</h1>
    <form action="/generate_link" method="post">
        <label for="user_id">Enter Your User ID( this represents the main users in the main usrs list. enter a name from the uses list main_user_id for example <b>user1</b> :</label><br>
        <input type="text" id="user_id" name="user_id"><br><br>
        <input type="submit" value="Generate Link">
    </form>
</body>
</html>
"""

# Route to generate a connection link
@app.route('/generate_link', methods=['POST'])
def generate_link():
    user_id = request.form.get('user_id') if request.form.get('user_id') in main_user_ids else None
    if user_id:
        token = generate_token()
        expiry_time = datetime.now() + TOKEN_EXPIRY_DURATION
        active_tokens[token] = (user_id, expiry_time)
        return f"Generated link from user {user_id}: <a href='/connect/{token}'>Click here to connect</a>"  # Return the generated token to the user
    else:
        return "Invalid user ID"



# Route to handle the connection link
@app.route('/connect/<token>', methods=['GET'])
def connect(token):
    if token in active_tokens:
        user_id, expiry_time = active_tokens[token]
        if datetime.now() < expiry_time:
            # Connection successful
            del active_tokens[token]  # Mark the token as used
            return f"You have grant access by {user_id}"
        else:
            return "Token expired"
    else:
        return "Invalid token"

if __name__ == '__main__':
    app.run(debug=True)