github.com/micro/go-micro/v2@v2.9.1/util/auth/auth.go (about)

     1  package auth
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	"github.com/micro/go-micro/v2/auth"
     8  	"github.com/micro/go-micro/v2/logger"
     9  )
    10  
    11  // Generate generates a service account for and continually
    12  // refreshes the access token.
    13  func Generate(id string, name string, a auth.Auth) error {
    14  	// extract the account creds from options, these can be set by flags
    15  	accID := a.Options().ID
    16  	accSecret := a.Options().Secret
    17  
    18  	// if no credentials were provided, generate an account
    19  	if len(accID) == 0 || len(accSecret) == 0 {
    20  		name := fmt.Sprintf("%v-%v", name, id)
    21  
    22  		opts := []auth.GenerateOption{
    23  			auth.WithType("service"),
    24  			auth.WithScopes("service"),
    25  		}
    26  
    27  		acc, err := a.Generate(name, opts...)
    28  		if err != nil {
    29  			return err
    30  		}
    31  		logger.Debugf("Auth [%v] Authenticated as %v issued by %v", a, name, acc.Issuer)
    32  
    33  		accID = acc.ID
    34  		accSecret = acc.Secret
    35  	}
    36  
    37  	// generate the first token
    38  	token, err := a.Token(
    39  		auth.WithCredentials(accID, accSecret),
    40  		auth.WithExpiry(time.Minute*10),
    41  	)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	// set the credentials and token in auth options
    47  	a.Init(
    48  		auth.ClientToken(token),
    49  		auth.Credentials(accID, accSecret),
    50  	)
    51  
    52  	// periodically check to see if the token needs refreshing
    53  	go func() {
    54  		timer := time.NewTicker(time.Second * 15)
    55  
    56  		for {
    57  			<-timer.C
    58  
    59  			// don't refresh the token if it's not close to expiring
    60  			tok := a.Options().Token
    61  			if tok.Expiry.Unix() > time.Now().Add(time.Minute).Unix() {
    62  				continue
    63  			}
    64  
    65  			// generate the first token
    66  			tok, err := a.Token(
    67  				auth.WithToken(tok.RefreshToken),
    68  				auth.WithExpiry(time.Minute*10),
    69  			)
    70  			if err != nil {
    71  				logger.Warnf("[Auth] Error refreshing token: %v", err)
    72  				continue
    73  			}
    74  
    75  			// set the token
    76  			a.Init(auth.ClientToken(tok))
    77  		}
    78  	}()
    79  
    80  	return nil
    81  }