#python #azure #flask
Вопрос:
Веб-приложение Python не может отображаться login.html
из templates
папки, что приводит к ошибке внутреннего сервера( 500
) , хотя оно отлично работает, когда я запускаю flask
приложение из локальной системы. Uri перенаправления заданы одинаковыми как в коде, так и на портале azure.
После устранения неполадок я узнал, что в azure не удается создать auth_url и сбой.
from flask import Flask,render_template,url_for,session,request,redirect
from flask_wtf.csrf import CSRFProtect
from flask_session import Session
from werkzeug.routing import BaseConverter
import msal,requests
csrf = CSRFProtect()
def page_not_found(e):
return render_template('404.html'), 404
def csrf_token_expired(e):
return render_template('400.html'), 400
def internal_server_error(e):
return render_template('500.html'), 500
app = Flask(__name__, static_folder='static', template_folder="templates")
app.config.from_object("config.DevelopmentConfig")
app.secret_key='Fpparesnal'
Session(app)
#app.config['SECRET_KEY'] = 'the random string'
app.register_error_handler(404, page_not_found)
app.register_error_handler(400, csrf_token_expired)
app.register_error_handler(500, internal_server_error)
#app.config.from_object("config.DevelopmentConfig")
csrf.init_app(app)
from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
@app.route("/home")
def home():
"""
This view returns the landing/home page of the tool.
"""
return render_template('home.html')
@app.route("/")
def index():
if not session.get("user"):
return redirect(url_for("login"))
return render_template('home.html', user=session["user"], version=msal.__version__)
@app.route("/login")
def login():
# Technically we could use empty list [] as scopes to do just sign in,
# here we choose to also collect end user consent upfront
print('Reached Login')
session["flow"] = _build_auth_code_flow(scopes=app.config['SCOPE'])
print(session["flow"]["auth_uri"],'auth_url')
return render_template("login.html", auth_url=session["flow"]["auth_uri"], version=msal.__version__)
@app.route(app.config['REDIRECT_PATH']) # Its absolute URL must match your app's redirect_uri set in AAD
def authorized():
try:
print('Reached Redirect path')
cache = _load_cache()
result = _build_msal_app(cache=cache).acquire_token_by_auth_code_flow(
session.get("flow", {}), request.args)
if "error" in result:
return render_template("auth_error.html", result=result)
session["user"] = result.get("id_token_claims")
_save_cache(cache)
except ValueError: # Usually caused by CSRF
pass # Simply ignore them
return redirect(url_for("index"))
@app.route("/logout")
def logout():
session.clear() # Wipe out user and its token cache from session
return redirect( # Also logout from your tenant's web session
app.config['AUTHORITY'] "/oauth2/v2.0/logout"
"?post_logout_redirect_uri=" url_for("index", _external=True))
@app.route("/graphcall")
def graphcall():
token = _get_token_from_cache(app.config['SCOPE'])
if not token:
return redirect(url_for("login"))
graph_data = requests.get( # Use token to call downstream service
app.config['ENDPOINT'],
headers={'Authorization': 'Bearer ' token['access_token']},
).json()
return render_template('display.html', result=graph_data)
def _load_cache():
cache = msal.SerializableTokenCache()
if session.get("token_cache"):
cache.deserialize(session["token_cache"])
return cache
def _save_cache(cache):
if cache.has_state_changed:
session["token_cache"] = cache.serialize()
def _build_msal_app(cache=None, authority=None):
return msal.ConfidentialClientApplication(
app.config['CLIENT_ID'], authority=authority or app.config['AUTHORITY'],
client_credential=app.config['CLIENT_SECRET'], token_cache=cache)
def _build_auth_code_flow(authority=None, scopes=None):
return _build_msal_app(authority=authority).initiate_auth_code_flow(
scopes or [],
redirect_uri=url_for("authorized", _external=True))
def _get_token_from_cache(scope=None):
cache = _load_cache() # This web app maintains one cache per session
cca = _build_msal_app(cache=cache)
accounts = cca.get_accounts()
if accounts: # So all account(s) belong to the current signed-in user
result = cca.acquire_token_silent(scope, account=accounts[0])
_save_cache(cache)
return result
app.jinja_env.globals.update(_build_auth_code_flow=_build_auth_code_flow)
Комментарии:
1. сначала вы должны проверить журналы на сервере, чтобы получить дополнительную информацию о внутренней проблеме. В конце концов вы можете попробовать запустить его в режиме отладки. Или вы должны записать собственную информацию в журналы или файлы. Обычно у меня ошибка 500, когда у меня проблемы с базой данных, а не с шаблонами.