在嵌套函数中设置值

Setting a value within a nested function

给了这个golang代码,因为我的golang生锈了,所以很难自由批评。基本的刷新令牌流程,但是我们将函数包装在 TX 函数中,以便在刷新流程出现问题时允许回滚。

我们需要 return newToken 值,但是它只保存我们在 refresh 函数期间需要的值,当它 return 到 refreshToken 取决于我是否通过它一个对象或指针分别是 returns 新的空标记或 nil。

package service

import (
    "context"
    "database/sql"
    "errors"
    "strings"

    "github.com/api-oauth/pkg/models"
    "github.com/api-oauth/pkg/repository"
    "golang.org/x/oauth2"
)

const minParts = 2

type OAuthAPI interface {
    Exchange(context.Context, string) (*oauth2.Token, error)
    Refresh(context.Context, string) (*oauth2.Token, error)
}

type Service struct {
    repo     repository.RepoInterface
    oauthAPI OAuthAPI
}

func New(api OAuthAPI, repo repository.RepoInterface) *Service {
    return &Service{repo: repo, oauthAPI: api}
}

var (
    ErrNoRefreshTokenFound = errors.New("no refresh token found")
    errNoScopesReturn      = errors.New("no scopes returned")
    errNoProfileFound      = errors.New("no profile found")
)

func (s *Service) RefreshToken(ctx context.Context, clientID string, userID int64) (*oauth2.Token, error) {
    var newToken *oauth2.Token

    err := s.repo.InTx(s.refresh(ctx, clientID, userID, newToken))
    if err != nil {
        return nil, err
    }

    return newToken, nil
}

func (s *Service) refresh(ctx context.Context, clientID string, userID int64, newToken *oauth2.Token) func(repo repository.Auth) error {
    return func(repo repository.Auth) error {
        oldToken, err := repo.GetToken(ctx, userID, clientID)
        if err != nil && err != sql.ErrNoRows {
            return err
        }

        if oldToken == nil {
            return ErrNoRefreshTokenFound
        }

        newToken, err = s.oauthAPI.Refresh(ctx, oldToken.Refresh)
        if err != nil {
            return err
        }

        rec := models.TokenRecord{
            UserID:    userID,
            ClientID:  clientID,
            ProfileID: oldToken.ProfileID,
            Access:    newToken.AccessToken,
            Refresh:   newToken.RefreshToken,
            Expiry:    newToken.Expiry,
        }

        err = repo.UpdateToken(ctx, &rec)
        if err != nil {
            return err
        }

        return nil
    }
}

正在尝试 RefreshToken return 更新的令牌信息

传递newToken的地址:

func (s *Service) RefreshToken(ctx context.Context, clientID string, userID int64) (*oauth2.Token, error) {
    var newToken *oauth2.Token

    err := s.repo.InTx(s.refresh(ctx, clientID, userID, &newToken))
    ...

然后,将 refresh 函数更改为:

func (s *Service) refresh(ctx context.Context, clientID string, userID int64, newToken **oauth2.Token) func(repo repository.Auth) error {
  ...
  *newToken, err=...