<commit_before>.. Flask-HTTPAuth documentation master file, created by
   sphinx-quickstart on Fri Jul 26 14:48:13 2013.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to Flask-HTTPAuth's documentation!
==========================================

**Flask-HTTPAuth** is a simple extension that simplifies the use of HTTP authentication with Flask routes.

Basic authentication example
----------------------------

The following example application uses HTTP Basic authentication to protect route ``'/'``::

    from flask import Flask
    from flask_httpauth import HTTPBasicAuth
    
    app = Flask(__name__)
    auth = HTTPBasicAuth()
    
    users = {
        "john": "hello",
        "susan": "bye"
    }
    
    @auth.get_password
    def get_pw(username):
        if username in users:
            return users.get(username)
        return None
    
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.username()
        
    if __name__ == '__main__':
        app.run()
        
The ``get_password`` callback needs to return the password associated with the username given as argument. Flask-HTTPAuth will allow access only if ``get_password(username) == password``.

If the passwords are stored hashed in the user database then an additional callback is needed::

    @auth.hash_password
    def hash_pw(password):
        return md5(password).hexdigest()

When the ``hash_password`` callback is provided access will be granted when ``get_password(username) == hash_password(password)``.

If the hashing algorithm requires the username to be known then the callback can take two arguments instead of one::

    @auth.hash_password
    def hash_pw(username, password):
        get_salt(username)
        return hash(password, salt)

For the most degree of flexibility the `get_password` and `hash_password` callbacks can be replaced with `verify_password`::

    @auth.verify_password
    def verify_pw(username, password):
        return call_custom_verify_function(username, password)

Digest authentication example
-----------------------------

The following example is similar to the previous one, but HTTP Digest authentication is used::

    from flask import Flask
    from flask_httpauth import HTTPDigestAuth
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret key here'
    auth = HTTPDigestAuth()
    
    users = {
        "john": "hello",
        "susan": "bye"
    }
    
    @auth.get_password
    def get_pw(username):
        if username in users:
            return users.get(username)
        return None
        
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.username()
        
    if __name__ == '__main__':
        app.run()

Security Concerns with Digest Authentication
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The digest authentication algorihtm requires a *challenge* to be sent to the client for use in encrypting the password for transmission. This challenge needs to be used again when the password is decoded at the server, so the challenge information needs to be stored so that it can be recalled later.

By default, Flask-HTTPAuth stores the challenge data in the Flask session. To make the authentication flow secure when using session storage, it is required that server-side sessions are used instead of the default Flask cookie based sessions, as this ensures that the challenge data is not at risk of being captured as it moves in a cookie between server and client. The Flask-Session and Flask-KVSession extensions are both very good options to implement server-side sessions.

As an alternative to using server-side sessions, an application can implement its own generation and storage of challenge data. To do this, there are four callback functions that the application needs to implement::

    @auth.generate_nonce
    def generate_nonce():
        """Return the nonce value to use for this client."""
        pass

    @auth.generate_opaque
    def generate_opaque():
        """Return the opaque value to use for this client."""
        pass

    @auth.verify_nonce
    def verify_nonce(nonce):
        """Verify that the nonce value sent by the client is correct."""
        pass

    @auth.verify_opaque
    def verify_opaque(opaque):
        """Verify that the opaque value sent by the client is correct."""
        pass

For information of what the ``nonce`` and ``opaque`` values are and how they are used in digest authentication, consult `RFC 2617 <http://tools.ietf.org/html/rfc2617#section-3.2.1>`_.

Custom Authentication Scheme Example
------------------------------------

The following example application uses a custom HTTP authentication scheme to protect route ``'/'`` with a token::

    from flask import Flask, g
    from flask_httpauth import HTTPTokenAuth

    app = Flask(__name__)
    auth = HTTPTokenAuth(scheme='Token')

    tokens = {
        "secret-token-1": "john",
        "secret-token-2": "<PASSWORD>"
    }

    @auth.validate_token
    def validate_token(token):
        if token in tokens:
            g.current_user = tokens[token]
            return True
        return False<commit_msg>Documentation fix, validate_token() -> verify_token()<commit_after>.. Flask-HTTPAuth documentation master file, created by
   sphinx-quickstart on Fri Jul 26 14:48:13 2013.
   You can adapt this file completely to your liking, but it should at least
   contain the root `toctree` directive.

Welcome to Flask-HTTPAuth's documentation!
==========================================

**Flask-HTTPAuth** is a simple extension that simplifies the use of HTTP authentication with Flask routes.

Basic authentication example
----------------------------

The following example application uses HTTP Basic authentication to protect route ``'/'``::

    from flask import Flask
    from flask_httpauth import HTTPBasicAuth
    
    app = Flask(__name__)
    auth = HTTPBasicAuth()
    
    users = {
        "john": "hello",
        "susan": "bye"
    }
    
    @auth.get_password
    def get_pw(username):
        if username in users:
            return users.get(username)
        return None
    
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.username()
        
    if __name__ == '__main__':
        app.run()
        
The ``get_password`` callback needs to return the password associated with the username given as argument. Flask-HTTPAuth will allow access only if ``get_password(username) == password``.

If the passwords are stored hashed in the user database then an additional callback is needed::

    @auth.hash_password
    def hash_pw(password):
        return md5(password).hexdigest()

When the ``hash_password`` callback is provided access will be granted when ``get_password(username) == hash_password(password)``.

If the hashing algorithm requires the username to be known then the callback can take two arguments instead of one::

    @auth.hash_password
    def hash_pw(username, password):
        get_salt(username)
        return hash(password, salt)

For the most degree of flexibility the `get_password` and `hash_password` callbacks can be replaced with `verify_password`::

    @auth.verify_password
    def verify_pw(username, password):
        return call_custom_verify_function(username, password)

Digest authentication example
-----------------------------

The following example is similar to the previous one, but HTTP Digest authentication is used::

    from flask import Flask
    from flask_httpauth import HTTPDigestAuth
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret key here'
    auth = HTTPDigestAuth()
    
    users = {
        "john": "hello",
        "susan": "bye"
    }
    
    @auth.get_password
    def get_pw(username):
        if username in users:
            return users.get(username)
        return None
        
    @app.route('/')
    @auth.login_required
    def index():
        return "Hello, %s!" % auth.username()
        
    if __name__ == '__main__':
        app.run()

Security Concerns with Digest Authentication
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The digest authentication algorihtm requires a *challenge* to be sent to the client for use in encrypting the password for transmission. This challenge needs to be used again when the password is decoded at the server, so the challenge information needs to be stored so that it can be recalled later.

By default, Flask-HTTPAuth stores the challenge data in the Flask session. To make the authentication flow secure when using session storage, it is required that server-side sessions are used instead of the default Flask cookie based sessions, as this ensures that the challenge data is not at risk of being captured as it moves in a cookie between server and client. The Flask-Session and Flask-KVSession extensions are both very good options to implement server-side sessions.

As an alternative to using server-side sessions, an application can implement its own generation and storage of challenge data. To do this, there are four callback functions that the application needs to implement::

    @auth.generate_nonce
    def generate_nonce():
        """Return the nonce value to use for this client."""
        pass

    @auth.generate_opaque
    def generate_opaque():
        """Return the opaque value to use for this client."""
        pass

    @auth.verify_nonce
    def verify_nonce(nonce):
        """Verify that the nonce value sent by the client is correct."""
        pass

    @auth.verify_opaque
    def verify_opaque(opaque):
        """Verify that the opaque value sent by the client is correct."""
        pass

For information of what the ``nonce`` and ``opaque`` values are and how they are used in digest authentication, consult `RFC 2617 <http://tools.ietf.org/html/rfc2617#section-3.2.1>`_.

Custom Authentication Scheme Example
------------------------------------

The following example application uses a custom HTTP authentication scheme to protect route ``'/'`` with a token::

    from flask import Flask, g
    from flask_httpauth import HTTPTokenAuth

    app = Flask(__name__)
    auth = HTTPTokenAuth(scheme='Token')

    tokens = {
        "secret-token-1": "john",
        "secret-token-2": "<PASSWORD>"
    }

    @auth.verify_token
    def verify_token(token):
        if token in tokens:
            g.current_user = tokens[token]
            return True
        return False
{'fraction_non_alphanumeric': 0.10541713854284636, 'fraction_numerical': 0.004907512268780672, 'mean_word_length': 2.9718890554722637, 'pattern_counts': {'":': 12, '<': 7, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6460035', 'n_tokens_mistral': 2787, 'n_tokens_neox': 2706, 'n_words': 1140}