diff --git "a/content/blog/Web\345\272\224\347\224\250\346\216\245\345\205\245OAuth2.en.md" "b/content/blog/Web\345\272\224\347\224\250\346\216\245\345\205\245OAuth2.en.md" index bd67b21..d6d1efd 100644 --- "a/content/blog/Web\345\272\224\347\224\250\346\216\245\345\205\245OAuth2.en.md" +++ "b/content/blog/Web\345\272\224\347\224\250\346\216\245\345\205\245OAuth2.en.md" @@ -1,108 +1,129 @@ --- -title: Web应用接入OAuth2 +title: Web OAuth 2.0 authorization date: 2023-12-27 19:41:20 tags: ["Web", "OAuth2", "Google", "Apple", "Facebook"] series: ["前端开发"] -category: ["blog","前端"] +category: ["blog", "前端"] featured: true - --- +Accessing third-party authorization login from Google, Apple, and Facebook was actually done several years ago. Coincidentally, there is a project that needs to be done again recently. I found some modifications to the interaction details, and the document is quite hidden. Therefore, I have compiled and summarized the document information for reference by my team colleagues later. + +To briefly introduce, OAuth (Open Authorization) is a token based authorization protocol. That is "Sign In with xxx". Mainstream platforms offer this authentication service, which allows us to authenticate and authorize login to our applications through third-party authentication providers. Enterprise level applications generally use this service, making it convenient for resource owners (RO) to use resource information on resource servers (RS). For more information, refer to the link below. + +## Documentation + +Introducing the OAuth2: -好几年前其实就做过这类需求了,刚好最近有一个项目又要接入 Google\Apple\Facebook 三方授权登录的需求,做的时候发现交互细节的修改,文档藏的比较深,所以整理汇总了下文档资料,方便后面给团队同事参考用。 -简单介绍下,OAuth(Open Authorization) 是一个基于令牌的授权协议。即 “Sign In with xxx”。主流平台都有提供的这项认证服务,可以通过第三方认证提供商进行身份验证和授权登录我们的应用,企业级应用一般都会上这个,方便资源拥有者(RO)使用在资源服务器(RS)的资源信息。更多了解参考下方链接。 +[理解 OAuth 2.0 - 阮一峰的网络日志](https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html) + +Sign In with Apple: -## 官方文档 -介绍 OAuth2 标准: -[理解OAuth 2.0 - 阮一峰的网络日志](https://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html) -Sign In with Apple: [https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js) + [https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple](https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple) -Sign In with Google: + +Sign In with Google: + [https://developers.google.cn/identity/protocols/oauth2/javascript-implicit-flow?hl=zh-cn](https://developers.google.cn/identity/protocols/oauth2/javascript-implicit-flow?hl=zh-cn) -Sign In with Facebook: + +Sign In with Facebook: + [https://developers.facebook.com/docs/facebook-login/](https://developers.facebook.com/docs/facebook-login/) + JS SDK [https://developers.facebook.com/docs/javascript/reference/v18.0](https://developers.facebook.com/docs/javascript/reference/v18.0) -手动构建登录流程,不走SDK [https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow#logindialog](https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow#logindialog) + +手动构建登录流程,不走 SDK [https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow#logindialog](https://developers.facebook.com/docs/facebook-login/guides/advanced/manual-flow#logindialog) + [使用 Facebook 登录功能和现有应用登录系统集成](https://developers.facebook.com/docs/facebook-login/guides/advanced/existing-system) + [https://developers.facebook.com/docs/facebook-login/guides/access-tokens](https://developers.facebook.com/docs/facebook-login/guides/access-tokens) 获取长期口令 + ## OAuth 工作流程 + #### 角色: -- 业务系统(我们的应用 Application) - - 前端(客户端 client ) - - 后台(客户端 API) -- 用户(Resource Owner) -- 认证服务(Authorization server,Google、Apple、微信、QQ等第三方授权服务器) -- 资源服务器 (Resource server) +- 业务系统(我们的应用 Application) + - 前端(客户端 client) + - 后台(客户端 API) +- 用户(Resource Owner) +- 认证服务(Authorization server,Google、Apple、微信、QQ 等第三方授权服务器) +- 资源服务器 (Resource server) + #### 流程: - - 客户端点击登录,此时浏览器导向授权服务器认证页面,携带客户端标识和重定向URI。客户端向授权服务器请求授权, - - 授权服务器验证参数,然后用户未登录需先登录,并选择是否给该客户端授权。 - - 用户同意授权,授权服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个code授权码(可能是get,也可能是post方式)。 - - 前端客户端收到授权码后,会通知客户端后台API,通过 POST 请求,附上上次的一样的"重定向URI",向授权服务器申请令牌(access_token)。这一步是在客户端的后端API隐藏式完成的,对前端侧的用户不可见。 - - 授权服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)或更新令牌(refresh token)。 - - 客户端收到token后,传回给前端view并更新页面,用户登录成功。 - - 以上登录流程已经完成,需要补充的是:此时客户端可以使用访问令牌向资源服务器请求资源了(具体要看申请了那些权限,如果只是email 和name,就没啥用)。 +- 客户端点击登录,此时浏览器导向授权服务器认证页面,携带客户端标识和重定向 URI。客户端向授权服务器请求授权, +- 授权服务器验证参数,然后用户未登录需先登录,并选择是否给该客户端授权。 +- 用户同意授权,授权服务器将用户导向客户端事先指定的"重定向 URI"(redirection URI),同时附上一个 code 授权码(可能是 get,也可能是 post 方式)。 +- 前端客户端收到授权码后,会通知客户端后台 API,通过 POST 请求,附上上次的一样的"重定向 URI",向授权服务器申请令牌(access_token)。这一步是在客户端的后端 API 隐藏式完成的,对前端侧的用户不可见。 +- 授权服务器核对了授权码和重定向 URI,确认无误后,向客户端发送访问令牌(access token)或更新令牌(refresh token)。 +- 客户端收到 token 后,传回给前端 view 并更新页面,用户登录成功。 +- 以上登录流程已经完成,需要补充的是:此时客户端可以使用访问令牌向资源服务器请求资源了(具体要看申请了那些权限,如果只是 email 和 name,就没啥用)。 + #### 几种模式: + **授权码模式(是最复杂的,也是最安全的,上面流程就是这种,推荐使用)** - - 客户端请求验证,由 用户获取 code - - 客户端后端拿着 code,去请求 token - - 销毁 code,下发 token,而用户拿不到 token,客户端保存 - - 客户端使用 token 访问资源服务器的资源 - - 过期后使用 refresh_token 刷新, token 再次使用 +- 客户端请求验证,由 用户获取 code +- 客户端后端拿着 code,去请求 token +- 销毁 code,下发 token,而用户拿不到 token,客户端保存 +- 客户端使用 token 访问资源服务器的资源 +- 过期后使用 refresh_token 刷新,token 再次使用 **简化模式(**为 web 浏览器应用设计,不支持 refresh token**)** - - 用户请求网站,如:http://www.baidu.com - - 重定向到一个授权页面 - - 用户登录,并同意授权 - - 重定向到网站,并带上access_token如:www.baidu.com?access_token=123 - - 访问 资源服务器的资源 - +- 用户请求网站,如:http://www.baidu.com +- 重定向到一个授权页面 +- 用户登录,并同意授权 +- 重定向到网站,并带上 access_token 如:www.baidu.com?access_token=123 +- 访问 资源服务器的资源 #### 以 Gitee 网站为例,使用 GitHub 账号登录(授权码模式) + 1、点击登录,触发到 GitHub 的认证页面 2、允许授权,302 重定向到 Gitee 的 redirect_uri 页面 -3、页面 接受 code 参数后,请求后端,由后端再去获取GitHub的 accessToken,返回给前端 -4、再次 302 重定向到 Gitee 首页,并携带Cookie,完成用户登录成功状态。 +3、页面 接受 code 参数后,请求后端,由后端再去获取 GitHub 的 accessToken,返回给前端 +4、再次 302 重定向到 Gitee 首页,并携带 Cookie,完成用户登录成功状态。 ```html https://github.com/login/oauth/authorize?client_id=5a179b878a9f6ac42acd& -redirect_uri=https%3A%2F%2Fgitee.com%2Fauth%2Fgithub%2Fcallback& -response_type=code&scope=user& +redirect_uri=https%3A%2F%2Fgitee.com%2Fauth%2Fgithub%2Fcallback& response_type=code&scope=user& state=bc9c9fb74d0ad5745f891bc370b9de1cafb46e2a417793fa - ``` + 认证后,重定向 -![认证后重定向](https://cdn.nlark.com/yuque/0/2023/png/203859/1703756156517-55c266f1-c8aa-4601-b2b2-b7035a7d6ba0.png#averageHue=%23363232&clientId=u1e30360e-97ca-4&from=paste&height=792&id=u9dd11888&originHeight=1188&originWidth=1624&originalType=binary&ratio=1.5&rotation=0&showTitle=true&size=224513&status=done&style=none&taskId=u01a3e0ad-3f6a-4667-9a5c-9e7afec5594&title=%E8%AE%A4%E8%AF%81%E5%90%8E%E9%87%8D%E5%AE%9A%E5%90%91&width=1082.6666666666667 "认证后重定向") +![认证后重定向](https://cdn.nlark.com/yuque/0/2023/png/203859/1703756156517-55c266f1-c8aa-4601-b2b2-b7035a7d6ba0.png "认证后重定向") + ```html https://gitee.com/auth/github/callback?code=9c637527cce64b8a5736&state=bc9c9fb74d0ad5745f891bc370b9de1cafb46e2a417793fa ``` -获取GitHub的 accessToken -![获取GitHub的 accessToken](https://cdn.nlark.com/yuque/0/2023/png/203859/1703756251104-6d3e2129-76fe-4619-9f69-1f901b1b69a6.png#averageHue=%23313131&clientId=u1e30360e-97ca-4&from=paste&height=778&id=ud62a00c9&originHeight=1167&originWidth=1604&originalType=binary&ratio=1.5&rotation=0&showTitle=true&size=216271&status=done&style=none&taskId=u2d21ba42-9456-4d96-ae08-1ec62c72f71&title=%E8%8E%B7%E5%8F%96GitHub%E7%9A%84%20accessToken&width=1069.3333333333333 "获取GitHub的 accessToken") + +获取 GitHub 的 accessToken +![获取 GitHub 的 accessToken](https://cdn.nlark.com/yuque/0/2023/png/203859/1703756251104-6d3e2129-76fe-4619-9f69-1f901b1b69a6.png "获取GitHub的 accessToken") 重定向到首页 -![重定向到首页](https://cdn.nlark.com/yuque/0/2023/png/203859/1703756570890-fcfa1b8c-2b94-4258-8d06-f60101329f5a.png#averageHue=%23d9ae57&clientId=u1e30360e-97ca-4&from=paste&height=800&id=u16650903&originHeight=1200&originWidth=1983&originalType=binary&ratio=1.5&rotation=0&showTitle=true&size=413240&status=done&style=none&taskId=u10797c3f-644f-49b9-b150-61011a0f15a&title=%E9%87%8D%E5%AE%9A%E5%90%91%E5%88%B0%E9%A6%96%E9%A1%B5&width=1322 "重定向到首页") -流程完成,下面分别介绍三种,我们应用用上的OAuth场景。 +![重定向到首页](https://cdn.nlark.com/yuque/0/2023/png/203859/1703756570890-fcfa1b8c-2b94-4258-8d06-f60101329f5a.png "重定向到首页") +流程完成,下面分别介绍三种,我们应用用上的 OAuth 场景。 + ## 集成 Apple 授权登录 (Sign in with Apple) + 苹果官方文档: -[https://developer.apple.com/documentation/sign_in_with_apple](https://developer.apple.com/documentation/sign_in_with_apple) (前端js调用,发起授权) -[https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api)( REST API ,后端同学看的) +[https://developer.apple.com/documentation/sign_in_with_apple](https://developer.apple.com/documentation/sign_in_with_apple) (前端 js 调用,发起授权) +[https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api](https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api)(REST API,后端同学看的) 第三方文档参考: [https://zhuanlan.zhihu.com/p/632483498](https://zhuanlan.zhihu.com/p/632483498) [Sign in with Apple NODE,苹果第三方登录](https://segmentfault.com/a/1190000020786994#item-4-5) [What the Heck is Sign In with Apple?](https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple) -Sign in with Apple Tutorial: +Sign in with Apple Tutorial: 1. [Sign in with Apple, Part 1: Apps](https://sarunw.com/posts/sign-in-with-apple-1) 2. [Sign in with Apple, Part 2: Private Email Relay Service](https://sarunw.com/posts/sign-in-with-apple-2) 3. [Sign in with Apple, Part 3: Backend – Token verification](https://sarunw.com/posts/sign-in-with-apple-3) 4. [Sign in with Apple, Part 4: Web and Other Platforms](https://sarunw.com/posts/sign-in-with-apple-4) -**授权码模式(和 Google 不同的是,redirect-url 回传的code需要有一个post接口来接收):** -```html +**授权码模式(和 Google 不同的是,redirect-url 回传的 code 需要有一个 post 接口来接收):** + +``` app client 向 app server 请求 oauth url app client 收到 url ,点击事件触发访问 oauth url, 跳转到 apple id server @@ -114,29 +135,37 @@ app server 验证 authorization code 和 id_token 是在同一个请求下发的 app server 成功返回用户信息给 app client ``` -![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703773909091-5843f905-22b0-4f51-a075-5ea98eb6ec04.png#averageHue=%23f3f3f3&clientId=u7f2dfee7-d8e6-4&from=paste&height=491&id=ucac3f60c&originHeight=491&originWidth=628&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93721&status=done&style=none&taskId=u5ac69480-0a9e-4bc9-84cc-fc73fd1334b&title=&width=628) -#### 注册&配置 OAuth2应用 -参考官方文档即可。主要是为了 获取客户端ID和客户端密钥:注册成功后,OAuth2提供商将为您的应用程序分配一个客户端ID和客户端密钥。还有重定向 redirectURI,这些凭据将在后续的OAuth2交互中使用。 -![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703754389135-2963205e-d366-44e6-931f-af6cc149a44f.png#averageHue=%23dedddd&clientId=u1e30360e-97ca-4&from=paste&height=475&id=u6d670983&originHeight=712&originWidth=804&originalType=binary&ratio=1.5&rotation=0&showTitle=false&size=180368&status=done&style=none&taskId=u0d1dd340-85fd-4b82-8fbc-0410946e589&title=&width=536) -当配置结束后,我们将获得我们所需的两个文件、三个ID、和一个URL连接,如下: -```jsx -redirectURI = 'https://xx.xxx.online/login/oauth-url' // 自己设置的重定向域名,可添加多个 -webClientId = 'com.xx.cn'; // 设置的client_id,一般是域名的反写 -teamId = 'xx'; // 10个字符的team_id -keyId = 'KOI23S78J6'; // 获取的10个字符的密钥标识符 +![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703773909091-5843f905-22b0-4f51-a075-5ea98eb6ec04.png) + +#### 注册&配置 OAuth2 应用 +参考官方文档即可。主要是为了 获取客户端 ID 和客户端密钥:注册成功后,OAuth2 提供商将为您的应用程序分配一个客户端 ID 和客户端密钥。还有重定向 redirectURI,这些凭据将在后续的 OAuth2 交互中使用。 +![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703754389135-2963205e-d366-44e6-931f-af6cc149a44f.png) + +当配置结束后,我们将获得我们所需的两个文件、三个 ID、和一个 URL 连接,如下: + +```jsx +redirectURI = "https://xx.xxx.online/login/oauth-url"; // 自己设置的重定向域名,可添加多个 +webClientId = "com.xx.cn"; // 设置的 client_id,一般是域名的反写 +teamId = "xx"; // 10 个字符的 team_id +keyId = "KOI23S78J6"; // 获取的 10 个字符的密钥标识符 ``` 设置登录徽标样式 + [https://appleid.apple.com/signinwithapple/button](https://appleid.apple.com/signinwithapple/button) -![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703775721626-23734410-a70c-4d7c-99c9-8aa6a88088bb.png#averageHue=%23fafafa&clientId=u7f2dfee7-d8e6-4&from=paste&height=483&id=u81212d96&originHeight=483&originWidth=571&originalType=binary&ratio=1&rotation=0&showTitle=false&size=44215&status=done&style=none&taskId=ud456e44c-8fc3-41c0-8cae-bb45a1a9d2c&title=&width=571) -#### Web 代码实现1( 这种是 OAuth 2.0 简化模式) -前端 SDK触发 + +![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703775721626-23734410-a70c-4d7c-99c9-8aa6a88088bb.png) + +#### Web 代码实现 1(这种是 OAuth 2.0 简化模式) + +前端 SDK 触发 + ```jsx -// 1\页面注入js sdk +// 1\页面注入 js sdk @@ -148,7 +177,7 @@ useEffect(() => { usePopup: true, redirectURI: redirectUrl, state: 'init00state', - responseType: 'code', // 有效值为code和id_token。 + responseType: 'code', // 有效值为 code 和 id_token。 }); }, [APPLEKey]); @@ -165,7 +194,7 @@ const data = await AppleID?.auth?.signIn({ ); console.log('APPLE signIn 的回调 datadatadata:', data); -// 4\处理响应、与自己的登录接口做交互,返回用户info,完成登录。 +// 4\处理响应、与自己的登录接口做交互,返回用户 info,完成登录。 if (data?.authorization?.code) { const authTokenLocal = jwt.decode(data?.authorization?.id_token) || {}; const oauthOpenId = get(authTokenLocal, 'sub'); @@ -177,7 +206,8 @@ if (data?.authorization?.code) { } ``` -APPLE 登录成功的回调 data, 拿着 id_token 和自己的 后端api 做绑定或登录,即完成业务。 +APPLE 登录成功的回调 data, 拿着 id_token 和自己的 后端 api 做绑定或登录,即完成业务。 + ```json { "authorization": { @@ -203,8 +233,11 @@ APPLE 登录成功的回调 data, 拿着 id_token 和自己的 后端api 做绑 } } ``` -#### Web 代码实现2( 这种是 授权模式) + +#### Web 代码实现 2(这种是 授权模式) + 手工触发 (授权模式) + ```jsx https://appleid.apple.com/auth/authorize?client_id=[CLIENT_ID]&redirect_uri=[REDIRECT_URI]&response_type=[RESPONSE_TYPE]&scope=[SCOPES]&response_mode=[RESPONSE_MODE]&state=[STATE] @@ -217,184 +250,193 @@ https://appleid.apple.com/auth/oauth2/v2/authorize ``` #### 登录流程 -用户点击 Apple 登录图标,会跳转到 Apple 登录网站,输入账号密码。首次登录会在任一 Apple设备弹出原生登录授权验证(双重验证),输入6位随机验证码 即可登录完成。 -![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703775181457-dc133d2b-a274-41e6-9e65-c841eda23224.png#averageHue=%23f1f1f1&clientId=u7f2dfee7-d8e6-4&from=paste&height=340&id=ue35bc92c&originHeight=340&originWidth=557&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23752&status=done&style=none&taskId=u0ab9e70f-cbf5-48b5-8c78-6ca6a1fced7&title=&width=557) -注意:首次登录会选择是否隐藏邮箱,选择隐藏将会使用apple提供的一个匿名邮箱而不是真实邮箱号。当选择信任浏览器后,之后在此浏览器中登录只需要输入账号、密码即可。 -![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703775215350-7bac5760-3198-46d4-8b7b-4eb9c1ef3bb1.png#averageHue=%23fcfcfc&clientId=u7f2dfee7-d8e6-4&from=paste&height=354&id=uedd78471&originHeight=354&originWidth=517&originalType=binary&ratio=1&rotation=0&showTitle=false&size=30409&status=done&style=none&taskId=u6c046b5b-6f26-42bc-9a6a-c4211f0b0b5&title=&width=517) -在登录后用户可以随时在apple设备上取消apple id在该程序上的授权登录。mac上safari浏览器上可直接验证登录。也可以通过手机号等其他方式进行验证,apple设备如果开启双重认证,会使用双重验证,简单说就是当你首次使用Apple登录一个设备时,在输入Apple id和密码之后,还需要在其他已登录的Apple设备上确认授权,并输入已登录设备上提供的验证码进行验证。 + +用户点击 Apple 登录图标,会跳转到 Apple 登录网站,输入账号密码。首次登录会在任一 Apple 设备弹出原生登录授权验证 (双重验证),输入 6 位随机验证码 即可登录完成。 + +![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703775181457-dc133d2b-a274-41e6-9e65-c841eda23224.png#taskId=u0ab9e70f-cbf5-48b5-8c78-6ca6a1fced7&title=&width=557) + +注意:首次登录会选择是否隐藏邮箱,选择隐藏将会使用 apple 提供的一个匿名邮箱而不是真实邮箱号。当选择信任浏览器后,之后在此浏览器中登录只需要输入账号、密码即可。 + +![image.png](https://cdn.nlark.com/yuque/0/2023/png/203859/1703775215350-7bac5760-3198-46d4-8b7b-4eb9c1ef3bb1.png) + +在登录后用户可以随时在 apple 设备上取消 apple id 在该程序上的授权登录。mac 上 safari 浏览器上可直接验证登录。也可以通过手机号等其他方式进行验证,apple 设备如果开启双重认证,会使用双重验证,简单说就是当你首次使用 Apple 登录一个设备时,在输入 Apple id 和密码之后,还需要在其他已登录的 Apple 设备上确认授权,并输入已登录设备上提供的验证码进行验证。 + #### 处理授权响应(分两种模式) + 用户单击“使用 Apple 登录”按钮后,框架会将授权信息发送给 Apple。Apple 处理授权请求后: -如果是 usePopup 模式,是直接返回 data【简化模式】; -否则会将包含授权结果的 HTTP POST 请求发送到 中提供的 URL redirectURI【授权码模式】 。 -HTTP 正文包含 content-type 为 application/x-www-form-urlencoded 的结果参数。成功的响应包含以下参数: + 如果是 usePopup 模式,是直接返回 data【简化模式】; + 否则会将包含授权结果的 HTTP POST 请求发送到 中提供的 URL redirectURI【授权码模式】 。 + +HTTP 正文包含 content-type 为 application/x-www-form-urlencoded 的结果参数。成功的响应包含以下参数: ## 集成 Google OAuth2 #### 需要注意 -##### 一、 google 的 gsi/client 和 oauth2 的区别 + +##### 一、google 的 gsi/client 和 oauth2 的区别 + > Google Identity Services (GIS) 的 gsi/client 是用于实现用户登录的 JavaScript 库。它可以帮助开发者在网页中集成“使用 Google 账号登录”的功能。当用户点击登录按钮后,gsi/client 会弹出一个 Google 登录界面,用户可以选择使用他们的 Google 账号进行登录。这样,开发者就可以通过 gsi/client 获取用户的身份信息,比如用户的邮箱地址等。 -> OAuth2 则是通过授权code,来获取访问令牌,然后使用该访问令牌来调用 Google API 或其他受保护的资源。 +> OAuth2 则是通过授权 code,来获取访问令牌,然后使用该访问令牌来调用 Google API 或其他受保护的资源。 综上: -gsi/client 用于前端直接新开一个弹窗,实现帮用户用Google实现登录网页的功能。【简化模式】 -OAuth2 则是先获取访问令牌后,Google重定向页面 URL 得到后授权码code,拿这个授权码去接口去授权,适合在不能弹窗的场景下使用。【授权码模式】 +gsi/client 用于前端直接新开一个弹窗,实现帮用户用 Google 实现登录网页的功能。【简化模式】 +OAuth2 则是先获取访问令牌后,Google 重定向页面 URL 得到后授权码 code,拿这个授权码去接口去授权,适合在不能弹窗的场景下使用。【授权码模式】 + ##### 二、不允许使用的嵌入式用户代理中 -Google的授权页面,在 Google 的 OAuth 2.0 政策中 disallowed_useragent 要求不能被webview嵌套。解决办法在下面: + +Google 的授权页面,在 Google 的 OAuth 2.0 政策中 disallowed_useragent 要求不能被 webview 嵌套。解决办法在下面: + Android 开发者在 android.webkit.WebView 中打开授权请求时可能会遇到此错误消息。开发者应该改用 Android 库,例如适用于 Android 的 Google 登录或 OpenID 基金会的 AppAuth for Android。当 Android 应用通过嵌入式用户代理打开常规 Web 链接,且用户从您的网站转到 Google 的 OAuth 2.0 授权端点时,Web 开发者可能会遇到此错误。开发者应允许在操作系统的默认链接处理程序(包括 Android App Links 处理程序或默认浏览器应用)中打开常规链接。Android 自定义标签页库也是一个受支持的选项。 + iOS 和 macOS 开发者在 WKWebView 中打开授权请求时可能会遇到此错误。开发者应该改用 iOS 库,例如适用于 iOS 的 Google 登录或 OpenID 基金会的 AppAuth for iOS。当 iOS 或 macOS 应用在嵌入式用户代理中打开常规 Web 链接,且用户从您的网站转到 Google 的 OAuth 2.0 授权端点时,Web 开发者可能会遇到此错误。开发者应允许操作系统的默认链接处理程序(包括通用链接处理程序或默认浏览器应用)中打开常规链接。SFSafariViewController 库也是一个受支持的选项。 -#### Web 代码实现1(这种属于 授权码模式) +#### Web 代码实现 1(这种属于 授权码模式) + 授权码模式是最复杂的,也是最安全的 - - 客户端发起请求验证,由用户获取 code - - 客户端拿到 code,请求 token - - 销毁 code,下发 token,而用户拿不到 token,客户端保存 - - 客户端使用 token 访问资源 - - 过期后使用 refresh_token 刷新, token 再次使用 +- 客户端发起请求验证,由用户获取 code +- 客户端拿到 code,请求 token +- 销毁 code,下发 token,而用户拿不到 token,客户端保存 +- 客户端使用 token 访问资源 +- 过期后使用 refresh_token 刷新,token 再次使用 + +Create form to request - Create form to request ```jsx /* - * Create form to request access token from Google's OAuth 2.0 server. - */ + * Create form to request access token from Google's OAuth 2.0 server. + */ const oauthSignIn = (key) => { - // Google's OAuth 2.0 endpoint for requesting an access token - const oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth'; - - // Create