Flask Сеансы на стороне сервера потеряны при использовании google-oauth - PullRequest
0 голосов
/ 23 мая 2019

У меня есть приложение для колб, которое использует сеанс колб для хранения данных. Я только что интегрировал 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 (). Не самое лучшее решение, но оно работало для меня на данный момент, пока я не смогу выделить больше времени, чтобы это выяснить.

...