快速搭建go语言web后端服务脚手架

快速搭建一个go语言web后端服务脚手架
源码下载:https://github.com/weloe/go-web-demo

web框架使用gin,数据操作使用gorm,访问控制使用casbin

首先添加一下自定义的middleware

recover_control.go ,统一处理panic error返回的信息

package middleware import ( "fmt" "github.com/gin-gonic/gin" "go-web-demo/component" "log" "net/http" ) func Recover(c *gin.Context) { defer func() { if r := recover(); r != nil { // print err msg log.Printf("panic: %v\n", r) // debug.PrintStack() // response same struct c.JSON(http.StatusBadRequest, component.RestResponse{Code: -1, Message: fmt.Sprintf("%v", r)}) } }() c.Next() }

access_control.go 使用casbin进行访问控制的中间件

package middleware

import (
	"fmt"
	"github.com/casbin/casbin/v2"
	gormadapter "github.com/casbin/gorm-adapter/v3"
	"github.com/gin-gonic/gin"
	_ "github.com/go-sql-driver/mysql"
	"go-web-demo/component"
	"log"
	"net/http"
)

// DefaultAuthorize determines if current subject has been authorized to take an action on an object.
func DefaultAuthorize(obj string, act string) gin.HandlerFunc {
   
	return func(c *gin.Context) {
   

		// Get current user/subject
		token := c.Request.Header.Get("token")
		if token == "" {
   
			c.AbortWithStatusJSON(http.StatusUnauthorized, component.RestResponse{
   Message: "token is nil"})
			return
		}
		username, err := component.GlobalCache.Get(token)
		if err != nil || string(username) == "" {
   
			log.Println(err)
			c.AbortWithStatusJSON(http.StatusUnauthorized, component.RestResponse{
   Message: "user hasn't logged in yet"})
			return
		}

		// Casbin enforces policy
		ok, err := enforce(string(username), obj, act, component.Enforcer)
		if err != nil {
   
			log.Println(err)
			c.AbortWithStatusJSON(http.StatusInternalServerError, component.RestResponse{
   Message: "error occurred when authorizing user"})
			return
		}
		if !ok {
   
			c.AbortWithStatusJSON(http.StatusForbidden, component.RestResponse{
   Message: "forbidden"})
			return
		}

		c.Next()
	}
}

func enforce(sub string, obj string, act string, enforcer *casbin.Enforcer) (bool, error) {
   
	// Load policies from DB dynamically
	err := enforcer.LoadPolicy()
	if err != nil {
   
		return false, fmt.Errorf("failed to load policy from DB: %w", err)
	}
	// Verify
	ok, err := enforcer.Enforce(sub, obj, act)
	return ok, err
}

func AuthorizeAdapterAndModel(obj string, act string, adapter *gormadapter.Adapter, model string) gin.HandlerFunc {
   
	return func(c *gin.Context) {
   

		// Get current user/subject
		token := c.Request.Header.Get("token")
		if token == "" {
   
			c.AbortWithStatusJSON(401, component.RestResponse{
   Message: "token is nil"})
			return
		}
		username, err := component.GlobalCache.Get(token)
		if err != nil || string(username) == "" {
   
			log.Println(err)
			c.AbortWithStatusJSON(401, component.RestResponse{
   Message: "user hasn't logged in yet"})
			return
		}

		// Load model configuration file and policy store adapter
		enforcer, err := casbin.NewEnforcer(model, adapter)
		// Casbin enforces policy
		ok, err := enforce(string(username), obj, act, enforcer)

		if err != nil {
   
			log.Println(err)
			c.AbortWithStatusJSON(500, component.RestResponse{
   Message: "error occurred when authorizing user"})
			return
		}
		if !ok {
   
			c.AbortWithStatusJSON(403, component.RestResponse{
   Message: "forbidden"})
			return
		}

		c.Next()
	}
}

reader.go 读取yaml配置文件的根据类,使用了viter

package config

import (
	"fmt"
	"github.com/sp
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值