У меня есть приложение для колб, которое использует сеанс колб для хранения данных. Я только что интегрировал Google oauth в приложение, и это сработало. Эта проблема возникла после изменения базового сеанса фляги на использование флеш-сеанса для сеансов на стороне сервера (в основном для того, чтобы в сеансе требовалось ограничение, превышающее 4 КБ). На этом этапе я получаю бесконечный цикл перенаправления.
Я запускаю это локально, используя pycharm. Я создал clientID и секретный ключ в API Google и добавил http://127.0.0.1:5000/oauth2callback в качестве авторизованного URL перенаправления. Я также добавил https://example.com/oauth2calback с локальной записью DNS, указывающей на сервер, на котором я его развертываю (через докер-контейнер)
Локально, кажется, все работает, даже при реализации сеансов на стороне сервера. Однако, как только я развернул это и ввел https://example.com, после аутентификации Google, я попал в бесконечный цикл перенаправления.
import ...
import google.oauth2.credentials
import google_auth_oauthlib.flow
from from flask_session import Session
app = Flask(__name__)
# Get if this is either dev env or prod env
# then set appropriate dev properties.
env = os.getenv('ENV', 'dev')
if env == 'dev':
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
app.config['SECRET_KEY'] = b'some super secret key'
# for server side sessions
## Commenting these two lines allows everything to work
app.config['SESSION_TYPE'] = 'filesystem'
Session(app)
GOOGLE_OAUTH2_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID")
GOOGLE_OAUTH2_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET")
REDIRECT_URI = '/oauth2callback'
CLIENT_CONFIG = {'web':{
'client_id':GOOGLE_OAUTH2_CLIENT_ID ,
'client_secret':GOOGLE_OAUTH2_CLIENT_SECRET,
'redirect_uris':["http://localhost:5000/oauth2callback"],
'auth_uri':"https://accounts.google.com/o/oauth2/auth",
'token_uri':"https://accounts.google.com/o/oauth2/token"
}}
SCOPES=["https://www.googleapis.com/auth/userinfo.profile","https://www.googleapis.com/auth/userinfo.email"]
def generate_csrf_token():
if '_csrf_token' not in session:
session['_csrf_token'] = some_random_string()
return session['_csrf_token']
def check_access_token():
login_bypass = not os.getenv('ENFORCE_LOGIN', False)
if login_bypass:
return True
return 'credentials' in session
@app.route('/login')
def login():
flow = google_auth_oauthlib.flow.Flow.from_client_config(CLIENT_CONFIG, scopes=SCOPES)
flow.redirect_uri = url_for('oauth2callback', _external=True)
authorization_url, state = flow.authorization_url(access_type='offline', include_granted_scopes='true')
session['state'] = state
return redirect(authorization_url)
def credentials_to_dict(credentials):
return {'token': credentials.token,
'refresh_token': credentials.refresh_token,
'token_uri': credentials.token_uri,
'client_id': credentials.client_id,
'client_secret': credentials.client_secret,
'scopes': credentials.scopes}
@app.route('/oauth2callback')
def oauth2callback():
state = session.get('state')
flow = google_auth_oauthlib.flow.Flow.from_client_config(CLIENT_CONFIG, scopes=SCOPES, state=state)
flow.redirect_uri = url_for('oauth2callback', _external=True)
authorization_response = request.url
flow.fetch_token(authorization_response=authorization_response)
credentials = flow.credentials
id_info = jwt.decode(credentials.id_token, verify=False)
email = id_info['email']
#allow anyone from example.com to log in
if email.split('@')[1] != "example.com":
return "Login failed!"
session['credentials'] = credentials_to_dict(credentials)
session.modified = True
#return render_template()
return redirect(url_for('loglist'))
@app.route("/")
@app.route("/loglist")
def loglist():
if not check_access_token():
return redirect(url_for('login'))
return "yay!"
после многих операторов печати в развернутом коде я вижу, что мой сеанс больше не включает ключ 'credentials', поэтому я перенаправлен обратно для входа в систему. Я предполагаю, что это как-то связано с DNS, так как кажется, что он работает без DNS (в некотором смысле через 127.0.0.1), хотя я не могу добавить частные IP-адреса к авторизованным URL-адресам Google для перенаправления для дальнейшей проверки.
Edit:
Мне удалось обойти это, используя модуль cachelib и инициализировав SimpleCache () / FileSystemCache (). Не самое лучшее решение, но оно работало для меня на данный момент, пока я не смогу выделить больше времени, чтобы это выяснить.