使用Google-OAuth丢失的Flask服务器端会话

时间:2019-05-23 19:27:12

标签: python session flask google-oauth flask-session

我有一个现有的flask应用程序,该应用程序使用flask会话存储数据。我刚刚将google oauth集成到应用程序中,并且此方法有效。在将基本的flask会话更改为将flask-session用于服务器端会话后,发生了此问题(主要是因为需要更多的会话限制(4kb))。此时,我得到了一个永无止境的重定向循环。

我正在使用pycharm在本地运行它。我已经在Google API中创建了一个clientID和机密,并添加了http://127.0.0.1:5000/oauth2callback作为授权的重定向URL。我还添加了https://example.com/oauth2calback并带有指向要在其上(通过docker容器)进行部署的服务器的本地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添加到Google的授权重定向URL中以进一步验证。

编辑:

我可以通过使用cachelib模块并初始化SimpleCache()/ FileSystemCache()来解决此问题。这不是最大的解决方案,但此刻对我有用,直到我可以花更多的时间解决这个问题。

0 个答案:

没有答案
相关问题