Python 3.x 如何将Google登录(Oauth2)限制为针对Flask WebApp的特定Google应用程序域的电子邮件?
开发一个Flask应用程序(Python3/Heroku)供公司内部使用,并成功实现了Google登录(Oauth2),在此基础上使用请求_oauthlib 研究表明,如果我在我的授权url中传递参数“hd”(托管域),它应该会起作用。例如 &hd=our\u google\u apps\u domain.com&access\u type=offline 我的理解是,这个参数应该提供客户端限制,并且只允许从我们的谷歌应用程序域(服务器端,我将在此之后处理!)的电子邮件登录,基于,以及这些stackoverflow帖子: 然而,尽管我的代码生成了我在上面粘贴的授权URL,但我仍然可以使用我的个人gmail帐户(@gmail.com vs@our apps domain.com)登录 有人能解释一下为什么这不起作用吗?还是提供一种不同的方法?基本上,我们更愿意阻止非员工登录 我可以根据需要共享代码,但基本上是从brijeshb42文章中粘贴的,基本上如下所示:Python 3.x 如何将Google登录(Oauth2)限制为针对Flask WebApp的特定Google应用程序域的电子邮件?,python-3.x,heroku,flask,google-oauth,Python 3.x,Heroku,Flask,Google Oauth,开发一个Flask应用程序(Python3/Heroku)供公司内部使用,并成功实现了Google登录(Oauth2),在此基础上使用请求_oauthlib 研究表明,如果我在我的授权url中传递参数“hd”(托管域),它应该会起作用。例如 &hd=our\u google\u apps\u domain.com&access\u type=offline 我的理解是,这个参数应该提供客户端限制,并且只允许从我们的谷歌应用程序域(服务器端,我将在此之后处理!)的电子邮件登录,基于,以及这些sta
OAuth2Session(
OUR_CLIENT_ID,
redirect_uri=https://OUR_APP.herokuapp.com/connect,
scope=['profile', 'email']).authorization_url(
https://accounts.google.com/o/oauth2/auth,
hd='our_google_apps_domain.com',
access_type='offline')
返回我在上面粘贴的认证url 成功验证后,您必须自己检查提供的电子邮件。我已经添加了您引用的我的文章中的代码片段。我在评论后添加了额外的检查要求
@app.route('/gCallback')
def callback():
# Redirect user to home page if already logged in.
if current_user is not None and current_user.is_authenticated():
return redirect(url_for('index'))
if 'error' in request.args:
if request.args.get('error') == 'access_denied':
return 'You denied access.'
return 'Error encountered.'
if 'code' not in request.args and 'state' not in request.args:
return redirect(url_for('login'))
else:
# Execution reaches here when user has
# successfully authenticated our app.
google = get_google_auth(state=session['oauth_state'])
try:
token = google.fetch_token(
Auth.TOKEN_URI,
client_secret=Auth.CLIENT_SECRET,
authorization_response=request.url)
except HTTPError:
return 'HTTPError occurred.'
google = get_google_auth(token=token)
resp = google.get(Auth.USER_INFO)
if resp.status_code == 200:
user_data = resp.json()
email = user_data['email']
"""
Your Domain specific check will come here.
"""
if email.split('@')[1] != 'domain.com':
flash('You cannot login using this email', 'error')
return redirect(url_for('login'))
user = User.query.filter_by(email=email).first()
if user is None:
user = User()
user.email = email
user.name = user_data['name']
print(token)
user.tokens = json.dumps(token)
user.avatar = user_data['picture']
db.session.add(user)
db.session.commit()
login_user(user)
return redirect(url_for('index'))
return 'Could not fetch your information.'
创建授权URL时,可以附加可选参数;附加hd=。。。这将起到关键作用:
auth_url, state = google.authorization_url(AUTH_URI, access_type='offline', hd='savv.ch')
这有很多好处。例如,如果用户登录到多个帐户,Google将自动选择正确的帐户(如果它与域匹配),这可能会在身份验证过程中节省一个步骤
如果我理解正确:在生成授权URL之前,您的应用程序应该检查该电子邮件是否在员工电子邮件列表中。如果不是,那么你不想让他们登录。如果我错了,请纠正我,但我对oauth2流的理解是,在他们登录/经过身份验证之前,你实际上不会收到电子邮件,因为他们将电子邮件输入谷歌登录页面,然后你会收到基于电子邮件的身份验证流的响应,例如。(很抱歉brijesh文章中的糟糕格式/和我一样)
google=get\u google\u auth(token=token)
resp=google.get(auth.USER\u INFO)
如果resp.status\u code==200:用户数据=resp.json()电子邮件=USER\u数据['email']
你是对的,你事先不知道电子邮件。我的建议是,不管谷歌怎么说,也要检查你的应用程序和用户的电子邮件。你必须将用户信息与应用程序中的用户进行匹配,因此如果你没有活动用户进行匹配,则身份验证应该失败。hd参数仍然有用,因为谷歌的然后系统可以自动选择正确的用户,并跳过验证过程中的一个步骤。Hrm,我需要重新测试——我以前使用过hd参数(1.5年前,它什么也没做)--也许现在能用了?谢谢brijesh--这就是我现在的想法。也许我可以接受这一点作为答案。但我会在一两周内不回答这个问题,因为现在我的问题是:1.如果没有客户端域限制,hd参数会做什么2.有没有办法做客户端限制?澄清一下#2--不是我要用客户端检查替换服务器端检查(显然不安全),但最好有一个门控机制,以避免人们可以通过个人电子邮件登录,授予权限,然后被拒绝登录。不是为了安全,而是为了用户体验。Hrm,你是说hd参数将限制gmail域名登录还是你的公司域名?以前没有。我最终由che解决了这个问题检查域并拒绝身份验证,因为hd参数似乎没有任何作用。我需要再次测试以验证。我没有使用hd='gmail.com'测试它(这不是很有用,因为任何人都可以创建gmail帐户),但是使用hd='corpdomain.com'它将仅限制登录该域)。您可能仍然应该在服务器端检查域,因为可能有人会从gmail帐户中伪造oauth进程。