The auth module provides authentication, authorization, session management, and token security for github.com/darkit/gin.
It wraps the underlying sa-token-go-style core with a project-friendly API that works at three levels:
gin.WithAuth(...)c.Auth() inside handlersSetGlobalManager(...), StpLogic, or a locally created Managerauth is designed to solve the runtime concerns of identity state management, not user data modeling.
Its core capabilities are:
What it does not do:
AuthContextManagerStpLogicUse gin.WithAuth(auth.AuthConfig{...}) when auth is part of the application runtime.
This creates a Manager during engine initialization and makes request auth available through c.Auth().
package main
import (
"time"
ginx "github.com/darkit/gin"
"github.com/darkit/gin/auth"
)
func main() {
e := ginx.New(
ginx.WithAuth(auth.AuthConfig{
Secret: "replace-me",
Expiry: 24 * time.Hour,
TokenStyle: auth.TokenStyleJWT,
}),
)
e.POST("/login", func(c *ginx.Context) {
token, err := c.Auth().Login("user-1001", "web")
if err != nil {
c.InternalError(err.Error())
return
}
c.Success(ginx.H{"token": token})
})
_ = e.Run(":8080")
}
Inside a handler, c.Auth() returns an *auth.AuthContext backed by the engine manager and current request.
This is the most convenient mode for business handlers.
func handleProfile(c *gin.Context) {
if err := c.Auth().CheckLogin(); err != nil {
c.Unauthorized(err.Error())
return
}
loginID, err := c.Auth().LoginID()
if err != nil {
c.Unauthorized(err.Error())
return
}
if err := c.Auth().CheckAnyPermission("user:read", "profile:read"); err != nil {
c.Forbidden(err.Error())
return
}
c.Success(gin.H{"login_id": loginID})
}
Use the global API when you want process-wide auth access without holding a manager reference. You must initialize it first.
cfg := auth.DefaultAuthConfig()
mgr := auth.NewManager(auth.NewMemoryStorage(), &cfg)
auth.SetGlobalManager(mgr)
defer auth.CloseGlobalManager()
token, err := auth.Login("user-1001", "web")
if err != nil {
panic(err)
}
ok := auth.IsLogin(token)
_ = ok
If you want middleware or auth logic without using global state, create and hold your own manager.
cfg := auth.DefaultAuthConfig()
storage := auth.NewMemoryStorage()
mgr := auth.NewManager(storage, &cfg)
builder := auth.NewMiddlewareBuilder(mgr)
router.Use(builder.AuthRequired())
router.GET("/admin", builder.RoleRequired("admin"), adminHandler)
Use StpLogic when one process hosts multiple auth domains that must not share manager state.
cfg := auth.DefaultAuthConfig()
adminMgr := auth.NewManager(auth.NewMemoryStorage(), &cfg)
userMgr := auth.NewManager(auth.NewMemoryStorage(), &cfg)
adminLogic := auth.NewStpLogic(adminMgr)
userLogic := auth.NewStpLogic(userMgr)
adminToken, _ := adminLogic.Login("admin-1", "web")
userToken, _ := userLogic.Login("user-1", "app")
_, _ = adminToken, userToken
AuthContext is the request-scoped facade.
It extracts the token from the incoming request, delegates to Manager, and offers a compact API for:
Token extraction follows manager config in this order:
TokenName)Authorization: Bearer <token>Manager is the module’s core runtime object.
All auth state eventually flows through it, whether called from AuthContext, global helpers, middleware, or StpLogic.
It is responsible for:
A Session is per-login-identity state stored in the configured backend.
It carries runtime metadata such as:
loginIddeviceloginTimepermissionsrolesPermissions and roles are persisted in session storage and can also be lazy-loaded through configured loaders.
A token is the login credential returned to the client.
The stored TokenInfo record currently includes:
LoginIDDeviceCreateTimeActiveTimeTag (field exists, but token tag APIs are not supported)Manager can also mark token state logically as:
KICK_OUTBE_REPLACEDauth.NewMemoryStorage() is the default when AuthConfig.Storage is nil.
Good for:
Characteristics:
auth.NewRedisStorage(redisURL) provides distributed storage.
Good for:
Characteristics:
SetKeepTTLClear() removes all keys reachable by the storage client and should be used with cautionExample:
storage, err := auth.NewRedisStorage("redis://localhost:6379/0")
if err != nil {
panic(err)
}
cfg := auth.DefaultAuthConfig()
cfg.Storage = storage
mgr := auth.NewManager(storage, &cfg)
_ = mgr
Manager.LoginWithRefreshToken(loginID, device) returns a token pair:
Manager.RefreshAccessToken(refreshToken) issues a new access token while preserving the login identity and device.
Important implementation details from the code:
TokenInfo semanticsNonce support is implemented through NonceManager and exposed via Manager.GenerateNonce() / VerifyNonce().
Properties:
This is useful for anti-replay scenarios around sensitive requests.
Manager.GetOAuth2Server() returns a storage-backed OAuth2 authorization server helper.
It supports:
The implementation stores client registrations, authorization codes, access tokens, and refresh tokens in the same configured storage backend.
cfg := auth.DefaultAuthConfig()
mgr := auth.NewManager(auth.NewMemoryStorage(), &cfg)
token, err := mgr.Login("user-1001", "web")
if err != nil {
panic(err)
}
if !mgr.IsLogin(token) {
panic("expected token to be valid")
}
loginID, err := mgr.GetLoginID(token)
if err != nil {
panic(err)
}
_ = loginID
_ = mgr.SetPermissions("user-1001", []string{"user:read", "user:*"})
_ = mgr.SetRoles("user-1001", []string{"admin"})
canRead := mgr.HasPermission("user-1001", "user:read")
canWrite := mgr.HasPermission("user-1001", "user:write")
isAdmin := mgr.HasRole("user-1001", "admin")
_, _, _ = canRead, canWrite, isAdmin
sess, err := mgr.GetSession("user-1001")
if err != nil {
panic(err)
}
_ = sess
pair, err := mgr.LoginWithRefreshToken("user-1001", "web")
if err != nil {
panic(err)
}
next, err := mgr.RefreshAccessToken(pair.RefreshToken)
if err != nil {
panic(err)
}
_ = next.AccessToken
builder := auth.NewMiddlewareBuilder(mgr)
r.Use(builder.AuthRequired())
r.GET("/reports", builder.PermRequired("report:read"), reportHandler)
r.GET("/ops", builder.RoleRequired("admin", "ops"), opsHandler)
AuthConfig.Validate() requires a non-empty Secret when TokenStyleJWT is selected.AuthConfig.Storage is optional; memory storage is used by default.NewManager(...) registers permission and role loaders if configured.Session for custom metadata.*, user:*, and segmented wildcard patterns such as user:*:view.Kickout marks the token as kicked out while removing the account mapping.Logout removes the token chain directly.