鉴权_Golang原生Web开发入门到微服务

基于golang的认证和鉴权

此处所采用的乃是 Go 语言的 Gin 框架,借助中间件这一途径来达成认证与鉴权之目的。

认证

基于请求头中的 Authorization 来开展认证工作,判别 token 是否存在,token 是否合法,将 token 中的角色信息等存置于上下文中。

func AuthMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		token := c.GetHeader(&#;Authorization&#;)
		if token == &#;&#; {
			utils.ResponseWithError(c, http.StatusUnauthorized, &#;未授权&#;)
			c.Abort()
			return
		}
		token = strings.TrimPrefix(token, &#;Bearer &#;)
		tokenMD5, err := config.RedisClient.Get(c, token).Result()
		if err != nil {
			utils.ResponseWithError(c, http.StatusUnauthorized, &#;token不存在&#;)
			c.Abort()
			return
		}
		// 解析 token
		claims, err := utils.ParseToken(tokenMD5)
		if err != nil {
			utils.ResponseWithError(c, http.StatusUnauthorized, &#;无效的 token&#;)
			c.Abort()
			return
		}
		// 将解析后的内容存入上下文
		c.Set(&#;permissions&#;, claims[&#;permissions&#;])
		c.Set(&#;userId&#;, claims[&#;userId&#;])
		// 继续执行
		c.Next()
	}
}

鉴权

凭借上下文中的角色信息来实施鉴权操作

func AuthorizationMiddleware(requiredPermissions []string) gin.HandlerFunc {
    return func(c *gin.Context) {
        // 获取用户权限列表
        permissions, exists := c.Get(&#;permissions&#;)
        if !exists {
            utils.ResponseWithError(c, http.StatusForbidden, &#;权限信息缺失&#;)
            c.Abort()
            return
        }

        // 转换成 []string
        userPermissions, ok := permissions.([]string)
        if !ok {
            utils.ResponseWithError(c, http.StatusForbidden, &#;权限数据格式错误&#;)
            c.Abort()
            return
        }

        // 检查用户是否拥有所需的权限
        for _, requiredPermission := range requiredPermissions {
            if !contains(userPermissions, requiredPermission) {
                utils.ResponseWithError(c, http.StatusForbidden, &#;权限不足&#;)
                c.Abort()
                return
            }
        }

        // 如果权限匹配,继续执行
        c.Next()
    }
}

// 检查权限列表是否包含某个权限
func contains(permissions []string, permission string) bool {
    for _, p := range permissions {
        if p == permission {
            return true
        }
    }
    return false
}

在路由中使用

r := gin.Default()

// 认证中间件
r.Use(AuthMiddleware())

// 使用鉴权中间件
r.GET(&#;/admin&#;, AuthorizationMiddleware(&#;admin&#;), func(c *gin.Context) {
    // 只有管理员才能访问这个路由
    c.JSON(http.StatusOK, gin.H{&#;message&#;: &#;Welcome Admin!&#;})
})

r.GET(&#;/user&#;, AuthorizationMiddleware(&#;user&#;), func(c *gin.Context) {
    // 只有普通用户才能访问这个路由
    c.JSON(http.StatusOK, gin.H{&#;message&#;: &#;Welcome User!&#;})
})
原文链接:,转发请注明来源!