SoFunction
Updated on 2025-04-11

Redis implements RBAC permission management

1. What is RBAC?

RBAC (Role-Based Access Control) is a common permission management model. It controls access permissions through user (User), role (Role), Permission and their mapping relationships. The basic idea of ​​RBAC is:

  • The user is assigned one or more roles;
  • Each role has certain permissions;
  • The user's role is determined by whether he has permission to access a resource.

2. Why use Redis to implement RBAC?

In traditional RBAC designs, permission data is usually stored in a database (such as MySQL), but this method may have the following problems:

  • Low query performance: multiple tables are required for each authentication, which affects the API response speed;
  • Not suitable for high concurrency: the database connection pool is limited, which may become a bottleneck in high concurrency scenarios;
  • Permission changes are inflexible: Database solutions usually require regular sync caches, otherwise the changes will not take effect immediately.

Advantages of using Redis as RBAC permission storage:

  • High performance: Redis is an in-memory database and has extremely fast query speed;
  • Low latency: Can be directlyO(1)Query permission data without complex SQL statements;
  • Support dynamic permission changes: user permission changes can take effect in real time without waiting for database updates;
  • Suitable for distributed systems: Multiple servers can share Redis permission data to avoid inconsistent states of different instances.

3. Design RBAC data structure

We use Redis as permission storage and design the following Key structure:

Key Value illustrate
user_roles:{user_id} ["admin", "editor"] User role list
role_permissions:{role} ["read", "write", "delete"] Permission list for roles
permission_routes:{permission} ["GET:/users", "POST:/articles"] Permission-corresponding API
blacklist_tokens Store logged out tokens Invalidate JWT and support active logout

4. Code implementation

We use Gin as the web framework and combine Redis for permission management.

📌 4.1 Installation dependencies

go get -u /gin-gonic/gin
go get -u /golang-jwt/jwt/v5
go get -u /redis/go-redis/v9

📌 4.2 Initialize Redis

package main

import (
	"context"
	"fmt"
	"log"

	"/redis/go-redis/v9"
)

// Initialize the Redis clientvar ctx = ()
var redisClient = (&{
	Addr: "127.0.0.1:6379", // Connect to Redis})

// Initialize RBAC Role & Permission Mappingfunc setupRBAC() {
	// Role → Permissions	(ctx, "role_permissions:admin", "read", "write", "delete")
	(ctx, "role_permissions:editor", "read", "write")
	(ctx, "role_permissions:viewer", "read")

	// Permissions → API	(ctx, "permission_routes:read", "GET:/users", "GET:/articles")
	(ctx, "permission_routes:write", "POST:/articles", "PUT:/articles")
	(ctx, "permission_routes:delete", "DELETE:/articles")

	// User → Role	(ctx, "user_roles:1", "admin")
	(ctx, "user_roles:2", "editor")
	(ctx, "user_roles:3", "viewer")

	("RBAC permission mapping initialization is completed")
}

📌 4.3 Generate JWT tokens

package main

import (
	"fmt"
	"time"

	"/golang-jwt/jwt/v5"
)

// JWT keyvar jwtSecret = []byte("supersecretkey")

// Generate JWT tokenfunc GenerateJWT(userID int) (string, error) {
	token := (jwt.SigningMethodHS256, {
		"user_id": userID,
		"exp":     ().Add(24 * ).Unix(), // Valid for 24 hours	})
	return (jwtSecret)
}

// parse JWT tokenfunc ParseJWT(tokenString string) (int, error) {
	token, err := (tokenString, func(token *) (interface{}, error) {
		return jwtSecret, nil
	})
	if err != nil || ! {
		return 0, ("invalid token")
	}

	claims, ok := .()
	if !ok {
		return 0, ("invalid claims")
	}

	return int(claims["user_id"].(float64)), nil
}

📌 4.4 Authentication middleware

// Access permission checkfunc hasAccess(userID int, method, path string) bool {
	// 1. Obtain user role	roles, err := (ctx, ("user_roles:%d", userID)).Result()
	if err != nil || len(roles) == 0 {
		return false
	}

	// 2. Traverse the role and obtain permissions	for _, role := range roles {
		permissions, _ := (ctx, ("role_permissions:%s", role)).Result()
		for _, permission := range permissions {
			routes, _ := (ctx, ("permission_routes:%s", permission)).Result()
			for _, route := range routes {
				if route == ("%s:%s", method, path) {
					return true
				}
			}
		}
	}

	return false
}

// RBAC Middlewarefunc RBACMiddleware()  {
	return func(c *) {
		tokenString := ("Authorization")
		if tokenString == "" {
			(401, {"error": "Token not provided"})
			()
			return
		}

		// Analysis JWT		userID, err := ParseJWT(tokenString)
		if err != nil {
			(401, {"error": "Token is invalid"})
			()
			return
		}

		// Check permissions		if !hasAccess(userID, , ()) {
			(403, {"error": "No access permission"})
			()
			return
		}

		("userID", userID)
		()
	}
}

📌 4.5 API Interface

func main() {
	r := ()
	setupRBAC()

	// Log in	("/login", func(c *) {
		userID := 1 // Suppose user 1 login		token, _ := GenerateJWT(userID)
		(200, {"token": token})
	})

	// Protected API	api := ("/api", RBACMiddleware())

	("/users", func(c *) {
		(200, {"message": "Get user list"})
	})

	("/articles", func(c *) {
		(200, {"message": "Create an article"})
	})

	("/articles", func(c *) {
		(200, {"message": "Delete Articles"})
	})

	(":8080")
}

5. Plan summary

✅ Redis storage permissions (recommended): efficient and suitable for distributed
✅ RBAC permission mapping: role permission mapping is clear
✅JWT Authentication: Stateless, suitable for API Authentication

In this way, you can use Redis to design an efficient set of RBAC permission management and support API mapping!

This is the end of this article about Redis implementing RBAC permission management. For more related Redis RBAC permission content, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!