Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x 如何将Google登录(Oauth2)限制为针对Flask WebApp的特定Google应用程序域的电子邮件?_Python 3.x_Heroku_Flask_Google Oauth - Fatal编程技术网

Python 3.x 如何将Google登录(Oauth2)限制为针对Flask WebApp的特定Google应用程序域的电子邮件?

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

开发一个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文章中粘贴的,基本上如下所示:

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进程。