Упрощение интеграции OAuth2 в GOA с помощью QBO: подробное руководство

OAuth2 — это широко распространенный протокол аутентификации и авторизации, обеспечивающий безопасный доступ к защищенным ресурсам на различных платформах. В этой статье мы рассмотрим, как интегрировать OAuth2 с GOA (платформой Go OpenAPI) и API QuickBooks Online (QBO). Мы предоставим примеры кода и обсудим несколько методов реализации OAuth2 с помощью GOA и QBO.

Метод 1: использование пакета go-oauth2-server

// Import required packages
import (
    "net/http"
    "github.com/go-oauth2/oauth2/v4"
    "github.com/go-oauth2/oauth2/v4/errors"
    "github.com/go-oauth2/oauth2/v4/generates"
    "github.com/go-oauth2/oauth2/v4/manage"
    "github.com/go-oauth2/oauth2/v4/models"
    "github.com/go-oauth2/oauth2/v4/server"
    "github.com/go-oauth2/oauth2/v4/store"
)
// Configure the OAuth2 server
func configureOAuth2Server() *server.Server {
    manager := manage.NewDefaultManager()
    // Configure token store (e.g., in-memory or database-based)
    manager.MustTokenStorage(store.NewMemoryTokenStore())
    // Configure client store (e.g., in-memory or database-based)
    clientStore := store.NewClientStore()
    clientStore.Set("client_id", &models.Client{
        ID:     "client_id",
        Secret: "client_secret",
    })
    manager.MapClientStorage(clientStore)
    // Configure password and client credentials grant types
    manager.MapGrantType(&oauth2.PasswordGrantHandler{
        PasswordTokenCfg: &config.Config{
            AccessTokenExp:    time.Hour,
            RefreshTokenExp:   time.Hour * 24 * 30,
            IsGenerateRefresh: true,
        },
    })
    manager.MapGrantType(&oauth2.ClientCredentialsGrantHandler{})
    // Create and configure the server
    srv := server.NewDefaultServer(manager)
    srv.SetAllowGetAccessRequest(true)
    srv.SetInternalErrorHandler(func(err error) (re *errors.Response) {
        log.Println("Internal Error:", err.Error())
        return
    })
    srv.SetResponseErrorHandler(func(re *errors.Response) {
        log.Println("Response Error:", re.Error.Error())
    })
    return srv
}
// Handle OAuth2 authorization requests
func handleOAuth2AuthorizationRequest(w http.ResponseWriter, r *http.Request) {
    err := srv.HandleAuthorizeRequest(w, r)
    if err != nil {
        http.Error(w, err.Error(), http.StatusBadRequest)
    }
}
// Handle OAuth2 token requests
func handleOAuth2TokenRequest(w http.ResponseWriter, r *http.Request) {
    err := srv.HandleTokenRequest(w, r)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
    }
}
// Define the main function to start the server
func main() {
    srv := configureOAuth2Server()
    // Set OAuth2 routes
    http.HandleFunc("/oauth2/authorize", handleOAuth2AuthorizationRequest)
    http.HandleFunc("/oauth2/token", handleOAuth2TokenRequest)
    // Start the server
    log.Fatal(http.ListenAndServe(":8080", nil))
}

Метод 2: использование пакета gin-oauth2

// Import required packages
import (
    "github.com/gin-gonic/gin"
    "github.com/go-oauth2/oauth2/v4/server"
    "github.com/go-oauth2/oauth2/v4/store"
    "github.com/go-session/session"
    "github.com/utrack/gin-csrf"
)
// Configure the OAuth2 server
func configureOAuth2Server() *server.Server {
    manager := manage.NewDefaultManager()
    // Configure token and client stores
    manager.MustTokenStorage(store.NewMemoryTokenStore())
    manager.MapClientStorage(store.NewClientStore())
    // Configure supported grant types
    manager.MapGrantType(password.NewDefaultPasswordGrant())
    // Create and configure the server
    srv := server.NewDefaultServer(manager)
    srv.SetAllowGetAccessRequest(true)
    srv.SetClientInfoHandler(server.ClientFormHandler)
    return srv
}
// Handle OAuth2 authorization requests
func handleOAuth2AuthorizationRequest(c *gin.Context) {
    err := srv.HandleAuthorizeRequest(c.Writer, c.Request)
    if err != nil {
        c.AbortWithError(http.StatusBadRequest, err)
    }
}
// Handle OAuth2 token requests
func handleOAuth2TokenRequest(c *gin.Context) {
    err := srv.HandleTokenRequest(c.Writer, c.Request)
    if err != nil {
        c.AbortWithError(http.StatusInternalServerError, err)
    }
}
// Define the main function to start the server
func main() {
    r := gin.Default()
    srv := configureOAuth2Server()
    // Set OAuth2 routes
    r.GET("/oauth2/authorize", handleOAuth2AuthorizationRequest)
    r.POST("/oauth2/token", handleOAuth2TokenRequest)
    // Start the server
    r.Run(":8080")
}

Метод 3. Использование пакета goth

// Import required packages
import (
    "github.com/markbates/goth"
    "github.com/markbates/goth/providers/oauth2"
)
// Configure the OAuth2 provider
func configureOAuth2Provider() {
    goth.UseProviders(
        oauth2.New(
            "client_id",
            "client_secret",
            "callback_url",
            "scope",
        ),
    )
}
// Handle OAuth2 callback
func handleOAuth2Callback(c *gin.Context) {
    user, err := goth.CompleteUserAuth(c.Writer, c.Request)
    if err != nil {
        c.AbortWithError(http.StatusInternalServerError, err)
        return
    }
// Handle authenticated user
    // ...
}
// Define the main function to start the server
func main() {
    r := gin.Default()
    configureOAuth2Provider()
    // Set OAuth2 callback route
    r.GET("/auth/callback", handleOAuth2Callback)
    // Start the server
    r.Run(":8080")
}

В этой статье мы рассмотрели три различных метода интеграции OAuth2 с GOA и QuickBooks Online API. Метод 1 продемонстрировал использование пакета go-oauth2-server, метод 2 — пакета gin-oauth2, а метод 3 — пакета goth. Каждый метод имеет свои преимущества и может быть выбран исходя из требований конкретного проекта. Следуя этим примерам кода и используя эти методологии, разработчики могут легко интегрировать аутентификацию и авторизацию OAuth2 с GOA и QBO, обеспечивая безопасный доступ к защищенным ресурсам.