Aquí hay una aplicación bastante sólido que se me ocurrió
A través de mi búsqueda, me encontré con un montón de implementaciones descuidados/incompletas de BasicAuth para GAE en línea. Como resultado, terminé escribiendo el mío. Este es el mejor/más simple enfoque que he podido proponer hasta ahora.
Considero una 'buena práctica' mantener los manejadores de solicitudes lo más delgados posible. Para reducir los estándares y copypasta en los manejadores, decidí implementar la autenticación como decorador. Para usarlo, simplemente conecte el decorador a los métodos get/post/put/delete del manejador.
Por ejemplo:
from decorators import basic_auth
class Handler(webapp2.RequestHandler):
@basic_auth
def get(self):
# load your page here
A continuación, agregue el decorador a decorators.py:
import base64
import os
from webapp2_extras import security
import yaml
def basic_auth(func):
def callf(webappRequest, *args, **kwargs):
# Parse the header to extract a user/password combo.
auth_header = webappRequest.request.headers.get('Authorization')
# if the auth header is missing popup a login dialog
if auth_header == None:
__basic_login(webappRequest)
else:
(username, password) = base64.b64decode(auth_header.split(' ')[1]).split(':')
if(__basic_lookup(username) == __basic_hash(password)):
return func(webappRequest, *args, **kwargs)
else:
__basic_login(webappRequest)
return callf
def __basic_login(webappRequest):
webappRequest.response.set_status(401, message="Authorization Required")
webappRequest.response.headers['WWW-Authenticate'] = 'Basic realm="Secure Area"'
def __basic_lookup(username):
accounts_file = os.getcwd() + os.sep + 'app' + os.sep + 'accounts.yaml'
stream = file(accounts_file, 'r')
for account in yaml.load(stream):
if account['username'] == username:
return account['password']
def __basic_hash(password):
return security.hash_password(password, method='sha1')
Nota: el prefijo subrayado doble se utilizan aquí en funciones que no deben estar visible fuera del módulo 'decoradores'.
En este caso, un intento de inicio de sesión fallido simplemente popup otro cuadro de diálogo de inicio de sesión, estoy usando la autenticación de una contraseña que se almacena en un archivo separado accounts.yaml, y las contraseñas se almacenan en una forma SHA1 hash.
El código está escrito para personalizar fácilmente:
- Modificar __basic_lookup() si necesita que sus contraseñas se almacenan en otro lugar (base de datos ex).
- Modificar __basic_hash() si sus contraseñas son de texto plano o codificadas con un método diferente.
- Modifique __basic_login() si desea una respuesta diferente a un intento fallido de inicio de sesión. Tales como un retraso artificial para prevenir ataques de fuerza bruta o un redireccionamiento.
¿Esto no significa que simplemente no confíes en que nadie encuentre el sitio dev .appspot.com? Si alguien lo encuentra, entonces puede acceder a él sin tener la 'capa' de autenticación básica frente a él. –