如何实现 Java OAuth 2.0 以登录 GitHub 和 Google
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
我们添加到 takipi 的最新功能之一是第三方登录。如果你像我一样懒惰,那么我猜你也更喜欢跳过填写表格和
设置新密码
。如果可用,许多人更喜欢第三方登录,只要他们要求的权限是非侵入性的——没有人真的希望随机帖子出现在他们的 Facebook 墙上,所以这种访问只包括用户的姓名和电子邮件地址等基本信息。在这篇文章中,您将了解到我们如何在 takipi 中实现这一点,如何在您的应用程序中使用 3rd 方登录以及我们遇到的一些见解,如果您决定集成,这些见解将为您节省一些宝贵的时间这与您自己的应用程序。
新帖子:如何实现 java oauth 2.0 以使用 github 和 google 登录 http://t.co/20hn59dctf pic.twitter.com/3tnnwpkjet
- takipi (@takipid) 2015 年 5 月 14 日
在我们自己的小宇宙中,事实证明我并不孤单,我们的许多用户也有同感。由于我们是一家开发工具初创公司,因此使用 github 和谷歌的第 3 方登录非常有意义。除了为您的用户带来便利之外,使用第三方服务还可以增强他们的安全性。由于 google 和 github 使用双因素身份验证 (2fa),您的应用程序可以“免费”享受这种级别的安全性。在我们的例子中,我们已经启用了 2fa,所以我想这让我们...... 3fa。
使用第 3 方登录按钮预览我们新主页的模型
要了解它在实践中的工作原理,您可以 查看我们用于内部测试的页面 。它完全有效,但更新尚未在网站上发布。您在这里有难得的机会成为第一个使用它的人。
所以提醒我 oauth 2.0 是如何再次出现的?
oauth 登录流程是这样的:用户访问您的站点,单击“使用任何方式登录”按钮并被重定向到权限页面。权限页面来自 whatever™,当他们批准您请求的权限时,whatever™ 向他们发送一个令牌,然后他的浏览器将该令牌发送到您的应用程序的后端。一旦您拥有了令牌,您就可以将它发送回 whatever™ 进行验证并假设它已经过验证——您可以访问您被授予权限的数据。
谷歌 oauth2.0 库
为了在我们的网站上实施第 3 方登录,我们使用了 google 的 java api 客户端库 。它还有 jackson2、protobuf 和出现在 github 顶级 java 项目使用的前 100 个库中的 各种其他方便的实用程序。这对我们来说是一个非常直接的选择,因为我们已经将这个库用于其他目的,而且,老实说,谷歌库刚刚成为……谷歌的第一个结果。准备好你的 锡纸帽子 。
使用谷歌实现登录
这是旅途中最轻松的部分;谷歌一端的 文档 清晰明了。因为它是他们自己的库,所以他们还抽象了部分过程并在幕后处理它,使其更容易实现。第一步是在 谷歌的开发者控制台 上创建一个项目,您可以在其中注册您的应用程序并自定义权限页面。
google 的权限页面 – 为 takipi 定制
现在回到java。从本质上讲,该过程可以归结为几个简单的步骤,毫不奇怪。首先,我们构建并执行请求以获取 googletokenresponse,以便我们可以验证从用户那里获得的令牌。然后我们使用此响应创建一个 googlecredential ,让我们对其调用 getaccesstoken() 并以 json 格式返回用户信息:
jsonfactory jsonfactory = new jacksonfactory();
httptransport httptransport = new nethttptransport();
googletokenresponse tokenresponse = new googleauthorizationcodetokenrequest(
httptransport, jsonfactory,
/* client id and secret */,
code, "postmessage").execute();
googlecredential credential = new googlecredential.builder()
.setjsonfactory(jsonfactory)
.settransport(httptransport)
.setclientsecrets(/* client id and secret */).build()
.setfromtokenresponse(tokenresponse);
oauth2 oauth2 = new oauth2.builder(httptransport, jsonfactory, credential).setapplicationname("yourappname").build();
tokeninfo tokeninfo = oauth2.tokeninfo().setaccesstoken(credential.getaccesstoken()).execute();
return oauth2.userinfo().get().execute();
繁荣。就是这样。这里最好的建议是只遵循官方文档。在 github 的最后,实现变得有点棘手。
使用github实现登录
现在我们意识到 google 帮助我们在 oauth 方面走捷径,并使用 googletokenresponse 和 googlecredential 的抽象。使用 github,我们必须更接近原始协议。与谷歌类似,我们可以在 github 的 开发者应用程序屏幕 上注册我们的应用程序时自定义权限屏幕。
github的权限页面——为takipi定制
当我们得到实际代码时,有 3 个主要问题使我们的速度有所降低,而且我们 在文档中 找不到。这是我们解决它们的方法:
1.建立自己的请求流程
在谷歌的案例中只有 5 行代码变成了 19 行,这样我们就可以生成一个 github 令牌响应。以下是自己构建请求的方法:
jsonfactory jsonfactory = new jacksonfactory();
httptransport httptransport = new nethttptransport();
googletokenresponse tokenresponse = new googleauthorizationcodetokenrequest(
httptransport, jsonfactory,
/* client id and secret */,
code, "postmessage").execute();
googlecredential credential = new googlecredential.builder()
.setjsonfactory(jsonfactory)
.settransport(httptransport)
.setclientsecrets(/* client id and secret */).build()
.setfromtokenresponse(tokenresponse);
oauth2 oauth2 = new oauth2.builder(httptransport, jsonfactory, credential).setapplicationname("yourappname").build();
tokeninfo tokeninfo = oauth2.tokeninfo().setaccesstoken(credential.getaccesstoken()).execute();
return oauth2.userinfo().get().execute();
2. 期待 json 响应?由于某种原因,字符串是默认值
注意到前面的初始化方法会设置接受吗?这有点令人惊讶。结果你需要明确要求 github 以 json 格式将响应发回给你,否则你将以字符串格式获得它。如果我们提前知道它可以节省我们一些时间来查看它:
但谢天谢地,我们找到了一些胶带和回形针来处理事情
3.处理github登录的用户邮件
现在,一位 github 用户可能拥有多个电子邮件地址,然后您必须选择要用于您自己目的的电子邮件地址。出于这个原因,我们创建了一个 getbestemail 方法来整理电子邮件数组(注意它应该扩展 arraylist 才能工作)。在对电子邮件数组进行排序后,我们选择了我们能找到的最佳选项:
jsonfactory jsonfactory = new jacksonfactory();
httptransport httptransport = new nethttptransport();
googletokenresponse tokenresponse = new googleauthorizationcodetokenrequest(
httptransport, jsonfactory,
/* client id and secret */,
code, "postmessage").execute();
googlecredential credential = new googlecredential.builder()
.setjsonfactory(jsonfactory)
.settransport(httptransport)
.setclientsecrets(/* client id and secret */).build()
.setfromtokenresponse(tokenresponse);
oauth2 oauth2 = new oauth2.builder(httptransport, jsonfactory, credential).setapplicationname("yourappname").build();
tokeninfo tokeninfo = oauth2.tokeninfo().setaccesstoken(credential.getaccesstoken()).execute();
return oauth2.userinfo().get().execute();
那么最好的选择是什么?我们从 github 的响应中获得的电子邮件数组中的每个字段都有一个电子邮件、一个已验证的字段和一个主要字段。这是我们为排序而实现的排序比较器:
jsonfactory jsonfactory = new jacksonfactory();
httptransport httptransport = new nethttptransport();
googletokenresponse tokenresponse = new googleauthorizationcodetokenrequest(
httptransport, jsonfactory,
/* client id and secret */,
code, "postmessage").execute();
googlecredential credential = new googlecredential.builder()
.setjsonfactory(jsonfactory)
.settransport(httptransport)
.setclientsecrets(/* client id and secret */).build()
.setfromtokenresponse(tokenresponse);
oauth2 oauth2 = new oauth2.builder(httptransport, jsonfactory, credential).setapplicationname("yourappname").build();
tokeninfo tokeninfo = oauth2.tokeninfo().setaccesstoken(credential.getaccesstoken()).execute();
return oauth2.userinfo().get().execute();
所以基本上你可以看到我们更喜欢经过验证的和主要的电子邮件。
结论
我们希望这篇文章能帮助您了解如何通过 google 和 github 的登录来处理 oauth 和 java。虽然这是我们决定实施它的方式,但您可以使用其他方式和库来实现类似的结果。我们很高兴听到您采用了哪种方法,您更喜欢哪些库,并回答有关此实现的任何问题。如果您对我们决定这样做的方式有任何意见或建议,请在下面的评论部分告诉我。如果您发现自己遇到麻烦,请分享您遇到的问题,我们很乐意提供帮助并分享更多代码。
帮助您更好地了解环境的 15 种工具—— 查看工具列表