当谈到身份认证功能时,我们常常会使用第三方认证库来简化流程。这些库中往往包含了用户身份的验证、访问令牌的生成、刷新和撤销等功能。
在 Go 语言中,我们可以使用一些成熟的第三方认证库,例如 goth。但是,使用它的时候我们发现一个问题:goth 并没有为所有的sns提供标准接口且第三方库的实现不稳定,因此我们需要封装goth库。接着我们将详细讲解如何使用 goth 库及其封装版本。
本攻略分为两个部分来讲述:第一个部分是关于如何使用 goth 库来实现第三方认证功能,第二个部分是关于如何封装 goth 库来提高代码的可重用性。
步骤一:使用 goth 库实现第三方认证功能
步骤 1:安装 goth 库
为了安装 goth 库,我们需要执行以下指令:
go get github.com/markbates/goth
步骤 2:遵循OAuth 2.0规范,创建新应用
在创建 API 应用时,你需要为你的站点申请访问 OAuth API 的凭证。通常情况下,申请凭证都是免费的。在申请凭证的过程中,通常你需要为你的应用指定一个回调 URL。该 URL 将用于 OAuth 服务器的授权回调,当授权完成时,授权服务器将使用该 URL 来回调你的应用,以返回授权码/访问令牌以进行下一步操作。
步骤 3:初始化 goth 库
在 goth 库中初始化你的认证策略。 在你的应用程序中,添加以下行来初始化 goth:
package main
import (
"github.com/gin-gonic/gin"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/facebook"
"github.com/markbates/goth/providers/google"
)
func init() {
goth.UseProviders(
facebook.New("key", "secret", "http://localhost:3000/auth/facebook/callback"),
google.New("key", "secret", "http://localhost:3000/auth/google/callback"),
)
}
上面的程序使用 Facebook 和 Google 作为认证提供程序。你可以使用不同的提供商和 callback URL 来适应你的应用,具体根据你的实际情况来实现。
步骤 4:定义你的认证请求处理程序
在你的请求处理程序中,你需要首先从请求参数中获取提供程序的名称。然后,你可以使用 goth 服务调用不同的身份验证提供程序 api 获取访问令牌。在获取到令牌之后,你可以将它们存储在会话中,或者将它们保存在服务器上以供以后使用。
func handleAuthRequest(c *gin.Context) {
provider := c.Param("provider")
// Authenticate user with provider
err := goth.BeginAuth(provider, nil)
if err != nil {
// Handle error
return
}
// Redirect user to authentication request
c.Redirect(http.StatusTemporaryRedirect, goth.CompleteAuthURL())
}
步骤 5:定义回调请求处理程序
在你的请求处理程序中,你需要获取的参数中包含授权代码。使用该代码调用 goth 服务以获取访问令牌。
func handleCallbackRequest(c *gin.Context) {
provider := c.Param("provider")
// Retrieve authorization code
code, err := c.URLQuery("code")
if err != nil {
// Handle error
return
}
// Get user access token information
creds, err := goth.CompleteAuth(provider, code)
if err != nil {
// Handle error
return
}
// Redirect user after successful authentication
c.Redirect(http.StatusTemporaryRedirect, "/")
}
步骤 6:完整的用户认证流程
用户认证的完整流程为以下六个步骤:
- 客户端请求身份验证页面。
- 用户完成身份验证并授权访问请求。
- 授权服务器将用户授权代码传递到应用程序。
- 应用程序调用 /auth/callback 路由获取访问/更新令牌。(如步骤 4)。
- 服务器获取令牌并将其存储在服务器端数据库中。
- 服务器将重定向用户到原页面。
步骤二:封装 goth 库
现在,我们考虑将 goth 库进行封装,以方便在其他项目中重复使用。为了实现这一目标,我们需要创建一个新的 Go 模块,然后创建一个新的包并在其中实现我们的封装代码。
步骤 1:创建新模块
首先,我们需要为我们的封装创建一个新模块。执行以下命令来创建一个名为 mylib 的新模块:
mkdir -p mylib && cd mylib
go mod init mylib
步骤 2:创建新包
接下来,我们将创建一个新包,以包含我们的封装代码。 执行以下命令来创建一个名为 mylib/auth 的新包:
mkdir auth && cd auth
接下来,让我们编写一些示例代码来说明如何使用我们通过 goth 库构建的身份验证框架。
步骤 3:编写示例代码
在 auth 包中创建一个名为 oauth.go 的文件,并添加以下示例代码:
package auth
import (
"github.com/markbates/goth"
"github.com/gin-gonic/gin"
)
type AuthorizationProvider interface {
Name() string
BeginAuthHandler(c *gin.Context)
CallbackHandler(c *gin.Context)
}
type OAuthProvider struct {
provider goth.Provider
}
func NewOAuthProvider(provider goth.Provider) *OAuthProvider {
return &OAuthProvider{provider: provider}
}
func (o *OAuthProvider) Name() string {
return o.provider.Name()
}
func (o *OAuthProvider) BeginAuthHandler(c *gin.Context) {
err := goth.BeginAuth(o.provider.Name(), nil)
if err != nil {
// Handle error
return
}
// Redirect user to authorization request URL
c.Redirect(301, goth.CompleteAuthURL())
}
func (o *OAuthProvider) CallbackHandler(c *gin.Context) {
// Retrieve authorization code/token and auth provider name
providerName := o.Name()
code, err := c.URLQuery("code")
if err != nil {
// Handle error
return
}
// Use goth to retrieve user access token information
creds, err := goth.CompleteAuth(providerName, code)
if err != nil {
// Handle error
return
}
// Use user information to log in user
// Redirect user to main page
c.Redirect(http.StatusTemporaryRedirect, "/")
}
在上面的示例代码中,我们创建了一个名为 AuthorizationProvider 的接口和 OAuthProvider 的实现。OAuthProvider 是一个中继实现,它使用 goth 提供程序作为底层实现,同时实现了 AuthorizationProvider 接口。
现在,使用我们之前创建的 auth 包,我们可以很容易地用以下代码初始化 goth 配置信息。
package main
import (
"mylib/auth"
"github.com/markbates/goth/providers/facebook"
"github.com/markbates/goth/providers/google"
)
func main() {
facebookOAuth := auth.NewOAuthProvider(
facebook.New("key", "secret", "http://localhost:3000/auth/facebook/callback"))
googleOAuth := auth.NewOAuthProvider(
facebook.New("key", "secret", "http://localhost:3000/auth/google/callback"))
goth.UseProviders(facebookOAuth, googleOAuth)
}
此代码实现了我们的第三方身份验证封装。 我们的代码相对简单,易于使用,同时为多个应用程序提供了可重用的身份验证代码。
在我们的示例中,auth 包中的 OAuthProvider 实现通过 goth 库为提供商名称提供了一种标准化的方式。 我们使用标准的 gin.Context 类型来处理回调和请求。
当我们在应用程序中需要新的身份验证提供程序时,我们仅需添加一个新的第三方项目,并使用我们的 OAuthProvider 类来封装它,而无需更改任何旧代码。
结论
在本教程中,我们已经学会了如何使用 goth 库来实现基本的第三方认证功能,并使用 goth 封装了一个可重用的身份验证框架。 这种方法为您的项目提供了一种简单而优雅的处理身份验证的方法,没有了底层实现的繁琐而又重复的工作。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:go goth封装第三方认证库示例详解 - Python技术站