uot;))
}
// Initialize cache to store current user in cache.
GlobalCache, err = bigcache.NewBigCache(bigcache.DefaultConfig(cacheConfig.ExpireTime * time.Second)) // Set expire time to 30 s
if err != nil {
log.Fatalf(fmt.Sprintf("failed to initialize cahce: %v", err))
}
}
func CreateCasbinEnforcer() {
var err error
// casbin model
config := config.Reader.ReadConfig().Casbin
if config == nil {
log.Fatalf(fmt.Sprintf("casbin config is nil"))
}
model := config.Model
//Initialize casbin adapter
adapter, _ := gormadapter.NewAdapterByDB(DB)
// Load model configuration file and policy store adapter
Enforcer, err = casbin.NewEnforcer(model, adapter)
if err != nil {
log.Fatalf(fmt.Sprintf("failed to create casbin enforcer: %v", err))
}
}
到这里准备工作基本完成,我们来写一个通用的 登录,注册,退出 业务吧
user_handler.go
package handler
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
"go-web-demo/component"
"go-web-demo/handler/request"
"go-web-demo/service"
"net/http"
)
func Login(c *gin.Context) {
loginRequest := &request.Login{}
err := c.ShouldBindBodyWith(loginRequest, binding.JSON)
if err != nil {
panic(fmt.Errorf("request body bind error: %v", err))
}
token := service.Login(loginRequest)
c.JSON(http.StatusOK, component.RestResponse{Code: 1, Data: token, Message: loginRequest.Username + " logged in successfully"})
}
func Logout(c *gin.Context) {
token := c.Request.Header.Get("token")
if token == "" {
panic(fmt.Errorf("token error: token is nil"))
}
bytes, err := component.GlobalCache.Get(token)
if err != nil {
panic(fmt.Errorf("token error: failed to get username: %v", err))
}
username := string(bytes)
// Authentication
// Delete store current subject in cache
err = component.GlobalCache.Delete(token)
if err != nil {
panic(fmt.Errorf("failed to delete current subject in cache: %w", err))
}
c.JSON(http.StatusOK, component.RestResponse{Code: 1, Data: token, Message: username + " logout in successfully"})
}
func Register(c *gin.Context) {
register := &request.Register{}
err := c.ShouldBindBodyWith(register, binding.JSON)
if err != nil {
c.JSON(400, component.RestResponse{Code: -1, Message: " bind error"})
return
}
service.Register(register)
c.JSON(http.StatusOK, component.RestResponse{Code: 1, Data: nil, Message: "register successfully"})
}
service.user.go
这里要注意 注册的时候我们做了两个操作,注册到user表,把policy写入到casbin_rule表,要保证他们要同时成功,所以要用事务
func Login(loginRequest *request.Login) string {
password := loginRequest.Password
username := loginRequest.Username
// Authentication
user := dao.GetByUsername(username)
if password != user.Password {
panic(fmt.Errorf(username + " logged error : password error"))
}
// Generate random uuid token
u, err := uuid.NewRandom()
if err != nil {
panic(fmt.Errorf("failed to generate UUID: %w", err))
}
// Sprintf token
token := fmt.Sprintf("%s-%s", u.String(), "token")
// Store current subject in cache
err = component.GlobalCache.Set(tok