设为首页 加入收藏

TOP

快速搭建一个go语言web后端服务脚手架(一)
2023-07-23 13:30:30 】 浏览:78
Tags:语言 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 := enf
首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇开源在线客服系统-客服系统历史消.. 下一篇sync.Pool:提高Go语言程序性能的..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目