Oauth 2.0在Golang中实施
#go #google #authentication #oauth2

介绍 :

安全毫无疑问,对于任何公共甚至私人服务或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来验证和授权。

Image description

先决条件ð:

要继续进行教程,首先,您需要安装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文件中创建GoogleLoginGoogleCallback函数

我们将使用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。它看起来像这样,

Image description

如果您已经签署了,则将显示该特定的邮件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。使用您的帐户登录。成功登录时,将显示您的数据。

Image description

所以,API准备就绪。此外,您可以通过将其连接到数据库并在应用程序中添加新用户,更多路由等来添加其他功能。

完整的代码保存在此GitHub存储库中。

结论ð::

Image description

要获取有关Golang概念,项目,资源等的更多信息。并且要保持在教程上的最新信息,请遵循Siddhesh on TwitterGitHub

在此之前继续学习,请继续建造ðð