谷歌身份验证怎么登录
I hate dealing with user authentication, so I’m very happy to make user management and authentication somebody else’s problem. “Somebody else” like Google. Handling user information securely, supporting various kinds of multi-factor authentication, enabling account recovery while avoiding account hijacking… those are all much better handled by Google than by me!
我讨厌处理用户身份验证,因此很高兴让用户管理和身份验证成为其他人的问题。 像Google这样的“其他人”。 安全地处理用户信息,支持各种多因素身份验证,在进行帐户恢复的同时避免帐户被劫持……Google所处理的一切都比我好得多!
Unfortunately for me, I found it pretty confusing to get Google to do that for me. Oh, there’s accurate and detailed information about how to do it on Google’s sites. A lot of information. About a lot of different ways to do it. Mostly using libraries that, for me at least, make it hard to debug things that I do wrong. So I decided to get down to basics and work through the fundamental steps, in detail, needed to have my server-side web apps use Google Sign-in. This blog post shows how I did it, and how you can do it if you want.
对我来说不幸的是,让Google为我做这件事让我感到非常困惑。 哦,在Google网站上有关于如何执行此操作的准确而详细的信息。 很多信息。 大约有许多不同的方法可以做到这一点。 大多数情况下,至少对于我来说,使用库会使调试我做错的事情变得困难。 因此,我决定深入基础知识,并详细地进行一些基本步骤,以使我的服务器端网络应用程序使用Google登录。 这篇博客文章显示了我是如何做到的,以及如果需要的话如何实现。
逻辑步骤 (Logical Steps)
I’m comfortable managing sessions for my app, so my real problem was verifying a user’s identity before I create such a session. The steps for that are:
我很愿意为我的应用程序管理会话,所以我的真正问题是在创建此类会话之前先验证用户的身份。 具体步骤如下:
The browser sends request to my app. My server checks whether there is a current active session, as indicated by a cookie it set and trusts. If there is, it’s okay, and my app returns the requested page. Otherwise, my app returns a web page stating that the user needs to authenticate to use the site further. The page has a link the user should click to do that. (Alternatively, my app could just send a redirect response to that link, but that’s pretty abrupt and might be confusing to the user.)
浏览器将请求发送到我的应用。 我的服务器检查是否存在当前活动的会话,如它设置并信任的cookie所示。 如果有,那没关系,我的应用程序返回请求的页面。 否则,我的应用程序将返回一个网页,指出用户需要进行身份验证才能进一步使用该网站。 该页面具有用户应该单击以执行此操作的链接。 (或者,我的应用程序可以向该链接发送重定向响应,但这很突然,可能会使用户感到困惑。)
The user clicks the link, and the browser sends a page request to Google. That link is to a Google page at accounts.google.com. The exact format of that link is described a bit later in this post. Google will return web pages and handle responses as needed to authenticate the user. If the authentication succeeds, Google will return a redirect response pointing to a page at my site.
用户单击链接,浏览器将页面请求发送给Google。 该链接在accounts.google.com谷歌的网页。 该链接的确切格式将在本文后面部分进行介绍。 Google将返回网页并根据需要处理响应以验证用户身份。 如果身份验证成功,Google将返回指向我站点页面的重定向响应 。
The user’s browser processes the redirect by sending a request to my app. My server uses information in that redirect URL to retrieve the user’s information from Google. This retrieval is from my web server to Google, not from the user’s browser. If everything goes right my server now knows who the user is, so the server creates a session and returns a response to the user that includes a header to set a cookie for that session. That response might be a web page, or a redirect back to the page the user originally requested. But now the user’s browser has a valid session cookie and the user can access my site.
用户的浏览器通过向我的应用发送请求来处理重定向。 我的服务器使用该重定向URL中的信息来从Google检索用户的信息。 此检索是从我的Web服务器到Google,而不是从用户的浏览器。 如果一切正常,我的服务器现在知道用户是谁,因此服务器创建一个会话并向用户返回响应 ,该响应包括用于为该会话设置cookie的标头。 该响应可能是网页,或者是重定向回用户最初请求的页面。 但是现在用户的浏览器具有有效的会话cookie,并且用户可以访问我的网站。
Of those three steps, my server has to deal with step 1, where it gets a request that may or may not have an active session associated with it, and if not, has to respond with a page or redirect with the exact right URL. That URL sends the user’s browser to Google for step 2; that’s Google’s to handle, so my app is not involved. Finally, Google redirects the browser back to my app for step 3, and my server has to use information in that redirect URL to get the user’s identity.
在这三个步骤中,我的服务器必须处理步骤1 ,在该步骤中 ,它会收到一个可能有或没有与之关联的活动会话的请求,如果没有,则必须用一个页面进行响应或使用正确的正确URL进行重定向。 该URL将用户的浏览器发送给Google进行第2步 ; 这是Google的处理方式,因此不涉及我的应用程序。 最后,Google将浏览器重定向回我的应用程序以执行第3步 ,并且我的服务器必须使用该重定向URL中的信息来获取用户的身份。
So let’s look at how an app handles step 1 and step 3. But first, there’s a step 0. Google is not going to identify a user when it’s asked to by just anybody. An application that wants to use Google Sign-in needs to register itself with Google first.
因此,让我们看一下应用程序如何处理步骤1和步骤3 。 但是首先是步骤0 。 当任何人要求Google都不会识别用户时。 想要使用Google登录的应用程序需要先向Google注册。
Let’s go through the steps you need in order to have your web server use Google sign-in.
让我们按照需要执行的步骤进行操作,以使您的Web服务器使用Google登录。
步骤0 —向Google注册该应用 (Step 0 — Register the app with Google)
You will need to create a Google Cloud Platform project at console.cloud.google.com. You can use a Gmail or G Suite account for this, or you can create a plain Google Cloud account when asked. You will probably have to provide a credit card, but there’s a generous free trial, you won’t get billed when the trial is up without first being notified, and in any case, this registration doesn’t require using any services that currently cost money.
您将需要在console.cloud.google.com上创建一个Google Cloud Platform项目。 您可以为此使用Gmail或G Suite帐户,也可以在询问时创建普通的Google Cloud帐户。 您可能需要提供一张信用卡,但是这里有一个免费的免费试用版,在试用期满时您无需先得到通知就不会付费,无论如何,此注册不需要使用当前需要付费的任何服务钱。
Once you have a project, use the menu on the left hand side of the console to select APIs & Services, then OAuth consent screen. Unless you intend to authenticate only users in a G Suite domain you control, your app will be considered External, so you will select that and click Create. Fill in the page with information about the app (you can name it anything you like) and save it. You’ll then need to go to the Credentials tab (you may be directed there automatically) and create an OAuth Client ID for your web application. As part of this you should register an Authorized redirect URL. That’s the URL in your app that will be called in Step 3.
有了项目后,请使用控制台左侧的菜单选择API和服务 ,然后选择OAuth同意屏幕 。 除非打算仅对您控制的G Suite域中的用户进行身份验证,否则您的应用将被视为外部应用,因此您将选择该应用并点击创建 。 在页面中填写有关该应用程序的信息(您可以随意命名)并保存。 然后,您需要转到“ 凭据”标签(可能会自动定向到该标签)并为您的Web应用程序创建OAuth客户端ID 。 在此过程中,您应该注册一个授权重定向URL 。 那就是您的应用程序中的URL,将在第3步中调用它。
When you finish this step you will have a CLIENT_ID and CLIENT_SECRET from the Credentials you created. You’ll also have selected and registered the REDIRECT_URI for Step 3. You’ll use those in the following steps.
完成此步骤后,您将从创建的凭据中获得CLIENT_ID和CLIENT_SECRET 。 您还将为步骤3选择并注册REDIRECT_URI 。将在以下步骤中使用它们。
第1步-提供登录网址 (Step 1 — Provide a sign-in URL)
When your server receives a request that doesn’t include a valid session cookie, it will reply either with a page that has a link to a specific sign-in address, or with a redirect response to that same address. The task for this step is to create that address.
当您的服务器收到不包含有效会话cookie的请求时,它将使用包含指向特定登录地址的链接的页面或指向该地址的重定向响应进行回复。 此步骤的任务是创建该地址。
The address is below, broken over several lines for display, but is all on one line for the actual app:
地址在下面,分成几行显示,但对于实际应用程序却全部位于一行上:
https://accounts.google.com/signin/oauth?
response_type=code&
client_id=CLIENT_ID&
scope=openid%20email&
redirect_uri=REDIRECT_URI&
state=STATEThe words in CAPITAL LETTERS all need to be replaced by the correct values. Step 0 provided those values for CLIENT_ID and REDIRECT_URI. The value for STATE can be almost any string you’d like — the URL the app is directed to in Step 3 will include it, so it’s a way to pass that information from this step to that step. I usually put the path of the page that was originally requested here.
大写字母中的所有单词都需要替换为正确的值。 步骤0为CLIENT_ID和REDIRECT_URI提供了这些值。 STATE的值几乎可以是您想要的任何字符串-应用程序在步骤3中指向的URL将包含它,因此这是一种将信息从此步骤传递到该步骤的方法。 我通常将最初请求的页面路径放在此处。
The response_type=code argument is asking for the eventual redirect request to include a code that can be used to retrieve information about the sign-in results. scope=open_id%20email says that the information the app wants is the signed-in user's email address.
response_type=code参数正在请求最终的重定向请求包括一个可用于检索有关登录结果信息的代码。 scope=open_id%20email表示应用程序所需的信息是登录用户的电子邮件地址。
第2步-验证用户 (Step 2 — Authenticate the user)
This is Google’s problem, not yours. But Google is going to check that:
这是Google的问题,而不是您的问题。 但是Google将检查以下内容:
The application asking for this is registered with Google (the CLIENT_ID)
要求此操作的应用程序已在Google中注册( CLIENT_ID )
The location to send the user back to (the REDIRECT_URI) is registered for that application
将用户发送回的位置( REDIRECT_URI )已为该应用程序注册
Google is also going to tell the user the name you gave the application when you registered it, and a link to the application’s privacy policy, if one was provided. Eventually, if the user consents and is authenticated, Google will send a redirect response to the user’s browser, which will then make a request to your server, beginning Step 3.
Google也将告诉用户您在注册时为应用程序提供的名称,以及提供该应用程序隐私权政策的链接(如果提供的话)。 最终,如果用户同意并通过身份验证,则Google会将重定向响应发送到用户的浏览器,然后浏览器将向您的服务器发出请求,从步骤3开始。
步骤3 —检索用户信息 (Step 3 — Retrieve the user information)
This step starts when the user’s browser makes a request to the REDIRECT_URI that the Google response specified. That request will include query parameters, and be of the form:
当用户的浏览器向Google响应指定的REDIRECT_URI发出请求时,此步骤开始。 该请求将包含查询参数,格式为:
REDIRECT_URI?state=STATE&code=CODE.You app’s server will use those query parameter values ( STATE and CODE) to get the user’s identity information. The value of STATE is just whatever value the server sent back in Step 1. That’s handy for keeping continuity from that step to this one, since so far as the server is concerned this request could have come from any user currently in the process of authenticating. There’s no other way for your server to know which page in your app the user was trying to access when told they needed to authenticate first.
您应用的服务器将使用这些查询参数值( STATE和CODE )来获取用户的身份信息。 STATE的值就是服务器在步骤1中发回的任何值。 这对于保持从这一步到这一步的连续性很方便,因为就服务器而言,此请求可能来自当前正在验证过程中的任何用户。 当服务器被告知需要先进行身份验证时,服务器没有其他方法可以知道用户尝试访问应用程序中的哪个页面。
The CODE value does not include any user information itself, but the server can use it to get that information. To do that, the server ( the user’s browser) will make an HTTP POST request to https://oauth2.googleapis.com/token, and the information needed will be returned as the body of the response. The POST request's body should have the content type application/x-www-form-urlencoded, and include the following values (as before, this is broken over multiple lines for clarity, but the request body should all be in a single line):
CODE值本身不包含任何用户信息,但是服务器可以使用它来获取该信息。 为此,服务器(用户的浏览器)将向https://oauth2.googleapis.com/token发出HTTP POST请求,并且所需的信息将作为响应的正文返回。 POST请求的正文应具有内容类型application / x-www-form-urlencoded ,并且应包含以下值(如前所述,为了清楚起见,将其分成多行,但请求正文均应在一行中):
code=CODE&
client_id=CLIENT_ID&
client_secret=CLIENT_SECRET&
redirect_uri=REDIRECT_URI&
grant_type=authorization_codeCODE is the value extracted from the query parameter the user’s browser sent. CLIENT_ID, CLIENT_SECRET, and REDIRECT_URI are the values from Step 0. And grant_type=authorization_code tells Google what kind of code your app's server is providing.
CODE是从用户浏览器发送的查询参数中提取的值。 CLIENT_ID , CLIENT_SECRET和REDIRECT_URI是步骤0中的值grant_type=authorization_code告诉Google您的应用服务器提供的代码类型。
The response to this POST request will be an application/json body containing information about the user. One field from this JSON object is called id_token, and its value is a JSON Web Token (JWT). That’s a digitally signed piece of data that includes fields about the user, including: the email address, the issuer (which will be https://accounts.google.com in this case), the audience (that is, the recipient this token is intended for, which is your app), and validity periods. You could do all the cryptography and parsing yourself, but the Python library google.oauth2.id_token can handle that, including verifying that the digital signature is valid and from Google.
对此POST请求的响应将是一个包含有关用户信息的application / json主体。 此JSON对象中的一个字段称为id_token ,其值是JSON Web令牌 (JWT)。 这是经过数字签名的数据,其中包含有关用户的字段,包括:电子邮件地址,发行者(在这种情况下为https://accounts.google.com ),受众(即此令牌的接收者)适用于您的应用)和有效期。 您可以进行所有加密操作并google.oauth2.id_token解析,但是Python库google.oauth2.id_token可以处理该问题,包括验证数字签名是否有效以及是否来自Google。
Once your server has this information, it can save the user’s information in a session object and set a cookie referring to that session. The authentication job is done.
服务器获得此信息后,便可以将用户信息保存在会话对象中,并设置引用该会话的cookie。 认证作业完成。
信息流 (Information Flows)
Information between your app’s server and the Google Sign-in service flows in two ways: indirectly, through the user’s browser, and directly from your app’s server to Google. The indirect information is provided in query parameters of URLs the browser requests, either in response to your app sending the browser to Google, or Google directing the browser back. Those query parameters include CLIENT_ID, REDIRECT_URI, STATE, and CODE.
应用程序服务器与Google登录服务之间的信息以两种方式流动:通过用户的浏览器间接进行,以及直接从应用程序服务器传递至Google。 响应于您的应用程序将浏览器发送给Google或Google引导浏览器返回,在浏览器请求的URL的查询参数中提供了间接信息。 这些查询参数包括CLIENT_ID , REDIRECT_URI , STATE和CODE 。
Sensitive information cannot be passed that way (via the browser) because it could be intercepted and used outside the context it is intended for. That’s why Google just sends an opaque code back to your app rather than the user’s email address. Sensitive information must pass directly and securely between your app’s server and Google’s service. That’s via the POST request and response in Step 3. That connection returns the user’s identity, which Google is only willing to provide to your registered app upon user approval, and passes the CLIENT_SECRET, which your server uses to prove its identity to Google.
敏感信息不能以这种方式(通过浏览器)传递,因为它可能在预期的上下文之外被截取和使用。 这就是Google只将不透明代码发送回您的应用程序而不是用户的电子邮件地址的原因。 敏感信息必须在应用服务器和Google服务之间直接安全地传递。 通过步骤3中的POST请求和响应。 该连接将返回用户的身份(Google仅在用户批准后才提供给您的已注册应用),并将CLIENT_SECRET传递给服务器,您的服务器使用CLIENT_SECRET来向Google证明其身份。
示例应用 (Sample app)
I’ve shared a sample application’s source code on GitHub, showing how all this can work in an extremely minimal web app. You can register a project for Google Cloud Platform and then run this code to try things out. I wrote the code for Google App Engine, but it should run pretty much anywhere. It could be on Cloud Run or Compute Engine, or a different cloud provider, or your own data center, or even your own desktop for testing. For the time being, you can try it out here.
我已经在GitHub上共享了一个示例应用程序的源代码 ,展示了所有这些如何在一个极小的Web应用程序中工作。 您可以为Google Cloud Platform注册一个项目,然后运行此代码进行尝试。 我为Google App Engine编写了代码,但它几乎可以在任何地方运行。 它可能在Cloud Run或Compute Engine上,或者在其他云提供商上,或者在您自己的数据中心,甚至在您自己的台式机上进行测试。 目前,您可以在这里尝试一下 。
Originally published athttp://engelke.devon July 14, 2020.
最初于 2020年7月14日 在 http://engelke.dev 上 发布 。
翻译自: https://medium.com/google-cloud/authenticating-users-with-google-sign-in-cb257d4fc722
谷歌身份验证怎么登录