介绍 :
安全毫无疑问,对于任何公共甚至私人服务或API来说,安全都是非常重要的功能,这是您需要大量关注才能正确的事情。
在本教程中,我们将看到对OAuth2的深入说明及其使用Golang的实现。
OAuth 2.0:
OAuth 2.0,代表开放授权,是一种旨在允许网站或应用程序代表用户访问其他Web应用程序的资源的标准。
OAuth 2.0是授权协议,而不是身份验证协议。因此,它主要是作为授予访问一组资源的一种手段,例如远程API或用户数据。
oauth 2.0使用访问令牌。访问令牌是一块数据,代表代表最终用户访问资源的授权。 OAuth 2.0没有定义用于访问令牌的特定格式。但是,在某些情况下,经常使用JSON Web令牌(JWT)格式。这使令牌发行人可以在令牌本身中包含数据。此外,出于安全原因,访问令牌可能有到期日期。
我们正在建立什么:
在本教程中,我们将使用Google API构建一个简单的API来验证和授权。
先决条件ð:
要继续进行教程,首先,您需要安装Golang和光纤。如果您尚未在Fiber Web框架系列中完成以前的教程,则可以看到它们here:)
安装:
入门ð:
让我们通过使用以下命令创建主要项目目录go-oauth2开始。
(ð¥请小心,有时我通过在代码中发表评论来完成解释)
mkdir jwt-auth-api //Creates a 'jwt-auth-api' directory
cd jwt-auth-api //Change directory to 'jwt-auth-api'
现在初始化一个mod文件。 (如果您发布模块,则必须是通过GO Tools下载模块的路径。这将是您的代码存储库。)
go mod init github.com/<username>/go-oauth2
安装光纤框架运行以下命令:
go get -u github.com/gofiber/fiber/v2
客户ID和客户秘密:
在向前推进之前,让我们获取Google API的客户ID和客户端秘密,我们将将其存储在.env文件中,并将其存储在我们的主要目录中。
请按照以下步骤获取Google API的客户凭证:
- 打开Google APIs console,单击凭据页面。
- 单击创建凭据> OAUTH客户端ID。选择
应用程序类型为Web应用程序,并添加
应用。对于本教程,我输入了该应用程序
Go-Auth2
. - 单击授权JavaScript起源下的添加URI,然后添加
http://localhost
。再次单击添加URI并添加http://localhost:8080
作为uri 2. - 单击授权重定向URI下的添加URI,然后添加
http://localhost:8080/google_callback
. - 复制显示的客户凭据。
获得凭据后,将它们存储在.env
文件中,如下所示。
GOOGLE_CLIENT_ID : <CLIENT_ID> //Replace <CLIENT_ID> with your ID.
GOOGLE_CLIENT_SECRET : <CLIENT_SECRET> //Replace <CLIENT_SECRET> with your SECRET.
初始化ð»:
让我们通过创建一个新的光纤实例来设置服务器。为此,创建一个文件main.go
并向其添加以下代码:
package main
import (
"github.com/Siddheshk02/go-oauth2/controllers" //imoprting the controllers package
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
app.Post("/google_login", controllers.GoogleLogin)
app.Post("/google_callback", controllers.GoogleCallback)
app.Listen(":8080")
}
首先,我们将在Google登录中工作。因此,目前在Google回调路线上发表评论。
现在,在此文件夹中创建google.go
文件。
我们将在google.go
文件中创建GoogleLogin
,GoogleCallback
函数
我们将使用golang.org/x/oauth2软件包,以安装它运行命令,
go get golang.org/x/oauth2
在执行这些功能之前,我们需要定义Google API的OAuth2配置。
让我们在config.go
文件中的GoogleConfig()
函数中定义oauth2.Config
变量对象GoogleLoginConfig
。为此,创建一个软件包/文件夹config
和文件夹中的文件config.go
。
package config
import (
"log"
"os"
"github.com/joho/godotenv"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
)
type Config struct {
GoogleLoginConfig oauth2.Config
}
var AppConfig Config
func GoogleConfig() oauth2.Config {
err := godotenv.Load(".env")
if err != nil {
log.Fatalf("Some error occured. Err: %s", err)
}
AppConfig.GoogleLoginConfig = oauth2.Config{
RedirectURL: "http://localhost:8080/google_callback",
ClientID: os.Getenv("GOOGLE_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_CLIENT_SECRET"),
Scopes: []string{"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile"},
Endpoint: google.Endpoint,
}
return AppConfig.GoogleLoginConfig
}
- redirecturl :重定向URL是OAuth流的关键部分。用户成功授权应用程序后,授权服务器将将用户重定向到应用程序。
- clientId :我们之前存储在.env文件中。 Client_ID是应用程序的公共标识符。第三方无法猜测,因此许多实施方式都使用了32个字符的十六进制字符串。如果客户ID是可以猜测的,则可以轻松地针对任意应用程序进行网络钓鱼攻击。它也必须在授权服务器处理的所有客户端中都是唯一的。
- clientsecret :我们早些时候存储在.env文件中。这 client_secret仅在应用程序和 授权服务器。这是应用程序的密码。它必须 足够随机以至于无法猜测,这意味着您 应避免使用常见的uuid库 说明服务器生成的时间戳或MAC地址 它。
- 范围:这是OAuth 2.0的一种机制来限制应用程序的 访问用户帐户。
使用以下代码更新main.go
,
package main
import (
"github.com/Siddheshk02/go-oauth2/config"
"github.com/Siddheshk02/go-oauth2/controllers"
"github.com/gofiber/fiber/v2"
)
func main() {
app := fiber.New()
config.GoogleConfig()
app.Get("/google_login", controllers.GoogleLogin)
//app.Post("/google_callback", controllers.GoogleCallback)
app.Listen(":8080")
}
现在,让我们在google.go
文件中使用函数GoogleLogin()
。
package controllers
import (
"github.com/Siddheshk02/go-oauth2/config"
"github.com/gofiber/fiber/v2"
)
func GoogleLogin(c *fiber.Ctx) error {
url := config.AppConfig.GoogleLoginConfig.AuthCodeURL("randomstate")
c.Status(fiber.StatusSeeOther)
c.Redirect(url)
return c.JSON(url)
}
randomstate
称为状态。它是保护用户免受CSRF攻击的代币。您必须始终提供一个非空字符串,并验证它与重定向回调上的状态查询参数匹配。
现在,让我们测试登录函数。运行命令go run main.go
。然后转到浏览器中的地址http://127.0.0.1:8080/google_login
。它看起来像这样,
如果您已经签署了,则将显示该特定的邮件ID并使用其他帐户选项。
现在,登录函数已完成。让我们创建GoogleCallback
函数。
func GoogleCallback(c *fiber.Ctx) error {
state := c.Query("state")
if state != "randomstate" {
return c.SendString("States don't Match!!")
}
code := c.Query("code")
googlecon := config.GoogleConfig()
token, err := googlecon.Exchange(context.Background(), code)
if err != nil {
return c.SendString("Code-Token Exchange Failed")
}
resp, err := http.Get("https://www.googleapis.com/oauth2/v2/userinfo?access_token=" + token.AccessToken)
if err != nil {
return c.SendString("User Data Fetch Failed")
}
userData, err := ioutil.ReadAll(resp.Body)
if err != nil {
return c.SendString("JSON Parsing Failed")
}
return c.SendString(string(userData))
}
在这里,我们将通过URL参数传递状态变量,我们将检查我们在GoogleLogin函数中设置的randomstate
,与我们获得的randomstate
匹配。如果匹配,那就是我们想要的正确数据。
接下来,我们将使用函数Exchange()
传递用于从Google服务器获取令牌的代码变量。
获得访问令牌后,我们将用户数据在变量resp
中获取。我们正在获得JSON响应并将其存储在userData
变量中。
让我们测试/google_callback route
。运行命令go run main.go
。然后转到浏览器中的地址http://127.0.0.1:8080/google_login
。使用您的帐户登录。成功登录时,将显示您的数据。
所以,API准备就绪。此外,您可以通过将其连接到数据库并在应用程序中添加新用户,更多路由等来添加其他功能。
。完整的代码保存在此GitHub存储库中。
结论ð::
要获取有关Golang概念,项目,资源等的更多信息。并且要保持在教程上的最新信息,请遵循Siddhesh on Twitter和GitHub。
在此之前继续学习,请继续建造ðð