[golang gin framework] 41. Gin mall project - background Rbac microservice after microservice actual combat (user login, Gorm database configuration and Consul configuration are separated separately)

The previous section extracted the captcha verification code function and integrated the verification code micro-service function. This section takes a look at the background Rbac function, and extracts the functions of user login, administrator management, role management, and authority management as micro-services. service to call

1. Introduction

The background operation is from logging in to the background home page, and then the administrator management, role management, authority management and other functions can be extracted as an Rbac microservice , because they are all related, and there are not too many users, of course, Each management function can also be operated independently as a microservice

2. Create the authority management Rbac microservice server and realize the background user login microservice

1. Generate authority management Rbac microservice code

Run in the server directory: go-micro new service rbac to generate rbac microservice server code

2. Write the proto/rbac.proto file to realize the user login microservice logic

Write user login related codes in this file , please refer to: [golang gin framework] 13. Gin mall project - configure public base class to achieve public success, failure prompt page user login, logout, and permission judgment
The reference code controllers/admin/loginController.go is as follows:
//执行登录操作
func (con LoginController) DoIndex(c *gin.Context) {
    //获取表单中的数据
    captchaId := c.PostForm("captchaId")     // 验证码id
    verifyValue := c.PostForm("verifyValue") //验证码的值
    //获取用户名以及密码
    username := c.PostForm("username")
    password := c.PostForm("password")

    // 1.判断验证码是否验证成功: 这里调用的是上一节验证码微服务的功能
    if flag := models.VerifyCaptcha(captchaId, verifyValue); flag {
        //2.查询数据库,判断用户以及密码是否正确
        userinfo := []models.Manager{}
        password = models.Md5(password)
        models.DB.Where("username = ? and password = ? ", username, password).Find(&userinfo)
        if len(userinfo) > 0 {
            //3.执行登录,保存用户信息,执行跳转操作
            session := sessions.Default(c)
            //注意: session.Set没法保存结构体对应的切片,所以需要把结构体转换成json字符串
            userinfoSlice, _ := json.Marshal(userinfo)
            session.Set("userinfo_admin", string(userinfoSlice))
            session.Save()
            con.Success(c, "登录成功", "/admin")
        } else {
            con.Error(c, "用户名或密码错误", "/admin/login")
        }
    } else {
        con.Error(c, "验证码验证失败", "/admin/login")
    }
}

It can be seen from the above: in the authority management Rbac microservice to achieve:

//2.查询数据库,判断用户以及密码是否正确
userinfo := []models.Manager{}
password = models.Md5(password)
models.DB.Where("username = ? and password = ? ", username, password).Find(&userinfo)

To implement the above logic, you need to connect to the database and create a data model. Here, use the GORM method

(1). Create a data model

Create manager.go under models, please refer to [golang gin framework] 13. Gin mall project - configure public base class to achieve public success, failure prompt page user login, logout, and permission judgment

package models

//管理员表

type Manager struct { // 结构体首字母大写, 和数据库表名对应, 默认访问数据表users, 可以设置访问数据表的方法
	Id  int
	Username string
	Password string
	Mobile string
	Email string
	Status int
	RoleId int
	AddTime int
	IsSuper int
}

//配置数据库操作的表名称
func (Manager) TableName() string {
	return "manager"
}

(2). Create conf/app.ini file

Create a conf/app.ini configuration file under the microservice project Rbac. Some configurations, such as: database configuration, redis configuration, and consul configuration information can be placed in this file for easy use. Use the configuration in this file and change it The data does not need to restart the project. For details, please refer to: [golang gin framework] 9. Use transactions and go-ini to load .ini configuration files in Gin GORM

app_name   = rbac
# possible values: DEBUG, INFO, WARNING, ERROR, FATAL

[mysql]
ip       = 127.0.0.1
port     = 3306
user     = root
password = 123456
database = ginshop

[consul]
#指定微服务的ip,一般一个微服务对应一台服务器,当在同一台服务器上有多个微服务时,以不同端口区分
addr   = localhost:8082

(3). Define the initInt.go file

Create the initInt.go file under models to automatically initialize app.ini . When app.ini is called in many places, you can intervene from here. The purpose of this file is to reduce code reuse

package models

//自动初始化app.ini:这里很多地方都要用到

import (
	"fmt"
	"os"
	"gopkg.in/ini.v1"
)

var Config *ini.File
var iniErr error

func init() {
	Config, iniErr = ini.Load("./conf/app.ini")
	if iniErr != nil {
		fmt.Printf("Fail to read file: %v", iniErr)
		os.Exit(1)
	}
}

 (4). Create initMysql.go

Create initMysql.go file under models , the purpose of this file is to create mysql database connection engine

package models

//https://gorm.io/zh_CN/docs/connecting_to_the_database.html
//微服务项目中: 推荐一个微服务对应一个数据库
import (
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

var DB *gorm.DB
var err error

func init() {
	//读取.ini里面的数据库配置,相关配置从initIni.go中读取
	ip := Config.Section("mysql").Key("ip").String()
	port := Config.Section("mysql").Key("port").String()
	user := Config.Section("mysql").Key("user").String()
	password := Config.Section("mysql").Key("password").String()
	database := Config.Section("mysql").Key("database").String()

	// dsn := "root:123456@tcp(192.168.0.6:3306)/gin?charset=utf8mb4&parseTime=True&loc=Local"
	dsn := fmt.Sprintf("%v:%v@tcp(%v:%v)/%v?charset=utf8mb4&parseTime=True&loc=Local", user, password, ip, port, database)
	DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{
		QueryFields: true, //打印sql
		//SkipDefaultTransaction: true, //禁用事务
	})
	// DB.Debug()
	if err != nil {
		fmt.Println(err)
	}
}

 (5). Write proto/rbac.proto file

Write the proto/rbac.proto file to realize the data logic related to microservices, please refer to: [golang gin framework] 39. Gin mall project - microservice architecture of microservice combat

syntax = "proto3";

package rbac;

option go_package = "./proto/rbac";

service Rbac {
    //登录操作
	rpc Login(LoginRequest) returns (LoginResponse) {}
}

//用户信息model:参考models/manager.go,一一对应
message ManagerModel{
	int64 id=1;
	string username=2;
	string password=3;
	string mobile=4;
	string email=5;
	int64 status=6;
	int64 roleId=7;
	int64 addTime=8;
	int64 isSuper=9;
}

//登录请求参数
message LoginRequest{
	string username=1;
	string password=2;
}

//登录返回参数
message LoginResponse{
	bool isLogin=1;
	repeated ManagerModel userlist=2;  //因为在client端需要返回用户相关信息userinfo,故定义一个切片
}

(6). Generate proto related files

Refer to [golang microservices] 7. go-micro framework introduction, go-micro scaffolding, go-micro combined with consul to build a microservice case , run the code under proto in the Makefile under windows: protoc --proto_path=. --micro_out= . --go_out=:. proto/captcha.proto, of course, if you are using go-micro for the first time, you need to run the code below init (@go xxx) to import related packages

   

(7). Initialize the server project

Initialize the project and import the packages required by the project

go mod init rbac
go mod tidy

If appear:

F:\www\go-data\src\go_code\micro\shop\server\rbac>go mod tidy
go: finding module for package go-micro.dev/v4/client
go: finding module for package gopkg.in/ini.v1
go: finding module for package go-micro.dev/v4
go: finding module for package go-micro.dev/v4/logger
go: finding module for package go-micro.dev/v4/server
go: finding module for package gorm.io/gorm
go: finding module for package gorm.io/driver/mysql
go: finding module for package go-micro.dev/v4/api
go: finding module for package google.golang.org/protobuf/proto
go: finding module for package google.golang.org/protobuf/reflect/protoreflect
go: finding module for package google.golang.org/protobuf/runtime/protoimpl
go: found go-micro.dev/v4 in go-micro.dev/v4 v4.10.2
go: found go-micro.dev/v4/logger in go-micro.dev/v4/logger v1.18.0
go: found gopkg.in/ini.v1 in gopkg.in/ini.v1 v1.67.0
go: found gorm.io/driver/mysql in gorm.io/driver/mysql v1.5.1
go: found gorm.io/gorm in gorm.io/gorm v1.25.2
go: found go-micro.dev/v4/api in go-micro.dev/v4/api v1.18.0
go: found go-micro.dev/v4/client in go-micro.dev/v4/client v1.18.0
go: found go-micro.dev/v4/server in go-micro.dev/v4/server v1.18.0
go: found google.golang.org/protobuf/proto in google.golang.org/protobuf v1.31.0
go: found google.golang.org/protobuf/reflect/protoreflect in google.golang.org/protobuf v1.31.0
go: found google.golang.org/protobuf/runtime/protoimpl in google.golang.org/protobuf v1.31.0
go: rbac/proto/rbac imports
        go-micro.dev/v4/api: go-micro.dev/v4/[email protected]: parsing go.mod:
        module declares its path as: github.com/micro/go-micro
                but was required as: go-micro.dev/v4/api

It means that the download of the " go-micro.dev/v4 " package failed, then you need to run the command  go get go-micro.dev/v4 , as shown in the figure:

 Then execute go mod tidy again , so that the import package in the project will be introduced without turning red

(8). Write handler/rbac.go user login microservice logic

because to achieve

//2.查询数据库,判断用户以及密码是否正确
userinfo := []models.Manager{}
password = models.Md5(password)
models.DB.Where("username = ? and password = ? ", username, password).Find(&userinfo)
		

Therefore, in handler/rbac.go, user-related information needs to be returned, and the user login logic code is as follows:

package handler

import (
	"context"
	"rbac/models"
	pb "rbac/proto/rbac"
)

type Rbac struct{}

//后台用户登录的微服务
func (e *Rbac) Login(ctx context.Context, req *pb.LoginRequest, res *pb.LoginResponse) error {
	managerList := []models.Manager{}
	err := models.DB.Where("username=? AND password=?", req.Username, req.Password).Find(&managerList).Error

	//处理数据
	var templist []*pb.ManagerModel
	for i := 0; i < len(managerList); i++ {
		templist = append(templist, &pb.ManagerModel{
			Id:       int64(managerList[i].Id),
			Username: managerList[i].Username,
			Password: managerList[i].Password,
			Mobile:   managerList[i].Mobile,
			Email:    managerList[i].Email,
			Status:   int64(managerList[i].Status),
			RoleId:   int64(managerList[i].RoleId),
			AddTime:  int64(managerList[i].AddTime),
			IsSuper:  int64(managerList[i].IsSuper),
		})
	}
	if len(managerList) > 0 {
		res.IsLogin = true
	} else {
		res.IsLogin = false
	}
	res.Userlist = templist

	return err
}

(9). Configure consul service discovery 

Configure consul service discovery in main.go

package main

import (
	"rbac/handler"
	"rbac/models"
	pb "rbac/proto/rbac"
	"go-micro.dev/v4"
	"go-micro.dev/v4/logger"
	"github.com/go-micro/plugins/v4/registry/consul"
)

var (
	service = "rbac"
	version = "latest"
)

func main() {
	//集成consul
	consulReg := consul.NewRegistry()
	// Create service

	//读取.ini里面的配置
	addr := models.Config.Section("consul").Key("addr").String()

	srv := micro.NewService(
		micro.Address(addr),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的client
		micro.Name(service),
		micro.Version(version),
		//注册consul
		micro.Registry(consulReg),
	)
	srv.Init(
		micro.Name(service),
		micro.Version(version),
	)

	// Register handler
	if err := pb.RegisterRbacHandler(srv.Server(), new(handler.Rbac)); err != nil {
		logger.Fatal(err)
	}
	// Run service
	if err := srv.Run(); err != nil {
		logger.Fatal(err)
	}
}

3. Start consul service discovery

Run the command in cmd: consul agent -dev, specific reference:  [golang microservice] 5. Microservice service discovery introduction, installation and use of consul, Consul cluster

4. Registration verification code microservice server to service discovery (consul)

Run go run main.go in the rbac directory, and then check in the consul UI to see if the registration is successful

Registered successfully 

 3. Create a permission management Rbac microservice client

1. First copy the server/rbac/proto folder to the project

2. Configure consul service discovery

Create initRbacConsul.go under models , and configure consul service discovery for calling. The code is as follows:

package models

//Rbac consul(服务发现)初始化配置
//微服务客户端配置: 初始化consul配置,当一个项目中多个微服务时,就很方便了
//建议:一个微服务对应一个客户端,这样好管理

import (
	"github.com/go-micro/plugins/v4/registry/consul"
	"go-micro.dev/v4"
	"go-micro.dev/v4/client"
	"go-micro.dev/v4/registry"
)

//RbacClient: 全局变量 在外部的包中可以调用
var RbacClient client.Client

//init 方法: 当程序运行时就会自动执行
func init() {
	consulRegistry := consul.NewRegistry(
		//指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client,建议一个微服务对应一个consul集群的client
		registry.Addrs("127.0.0.1:8500"),
	)
	// Create service
	srv := micro.NewService(
		micro.Registry(consulRegistry),
	)
	srv.Init()

	RbacClient = srv.Client()
}

 Here, maybe not introduced, execute the command: go mod tidy imports the corresponding package

3. Call the Rbac microservice 

Call the Rbac microservice in the  DoIndex method of controllers/admin/login.go

The original DoIndex method code is as follows: 


//执行登录操作
func (con LoginController) DoIndex(c *gin.Context) {
	//获取表单中的数据
	captchaId := c.PostForm("captchaId")     // 验证码id
	verifyValue := c.PostForm("verifyValue") //验证码的值
	//获取用户名以及密码
	username := c.PostForm("username")
	password := c.PostForm("password")

	// 1.判断验证码是否验证成功
	if flag := models.VerifyCaptcha(captchaId, verifyValue); flag {
		//2.查询数据库,判断用户以及密码是否正确
		userinfo := []models.Manager{}
		password = models.Md5(password)
		models.DB.Where("username = ? and password = ? ", username, password).Find(&userinfo)
		if len(userinfo) > 0 {
			//3.执行登录,保存用户信息,执行跳转操作
			session := sessions.Default(c)
			//注意: session.Set没法保存结构体对应的切片,所以需要把结构体转换成json字符串
			userinfoSlice, _ := json.Marshal(userinfo)
			session.Set("userinfo_admin", string(userinfoSlice))
			session.Save()
			con.Success(c, "登录成功", "/admin")
		} else {
			con.Error(c, "用户名或密码错误", "/admin/login")
		}
	} else {
		con.Error(c, "验证码验证失败", "/admin/login")
	}
}

 Then call the Rbac microservice in //2. Query the database to determine whether the user and password are correct . The code is modified as follows:

//这里需要import (
//     "context"
//	 pbRbac "goshop/proto/rbac"
//    )

//执行登录操作
func (con LoginController) DoIndex(c *gin.Context) {
	//获取表单中的数据
	captchaId := c.PostForm("captchaId")     // 验证码id
	verifyValue := c.PostForm("verifyValue") //验证码的值
	//获取用户名以及密码
	username := c.PostForm("username")
	password := c.PostForm("password")

	// 1.判断验证码是否验证成功
	if flag := models.VerifyCaptcha(captchaId, verifyValue); flag {
		//2.查询数据库,判断用户以及密码是否正确
		//userinfo := []models.Manager{}
		//password = models.Md5(password)
		//models.DB.Where("username = ? and password = ? ", username, password).Find(&userinfo)
		//调用Rbac微服务
		rbacClient := pbRbac.NewRbacService("rbac", models.RbacClient)
		res, _ := rbacClient.Login(context.Background(), &pbRbac.LoginRequest{
			Username: username,
			Password: models.Md5(password),
		})
		//通过Rbac微服务结果,判断是否登录
		if res.IsLogin {
			//3.执行登录,保存用户信息,执行跳转操作
			session := sessions.Default(c)
			//注意: session.Set没法保存结构体对应的切片,所以需要把结构体转换成json字符串
			userinfoSlice, _ := json.Marshal(res.Userlist)  //res.Userlist:微服务返回的用户信息
			session.Set("userinfo_admin", string(userinfoSlice))
			session.Save()
			con.Success(c, "登录成功", "/admin")
		} else {
			con.Error(c, "用户名或密码错误", "/admin/login")
		}
	} else {
		con.Error(c, "验证码验证失败", "/admin/login")
	}
}

Ok, the client code of the authority management Rbac microservice server is ok, and then verify whether the Rbac microservice is successful

4. Verify authority management Rbac microservice function

1. Start the server first

See [golang gin framework] 40. Gin Mall Project - Captcha verification code microservice code in microservice combat , here you need to start the verification code captcha microservice server code.

2. Start the client

Run in the project root directory: go run main.go to start the project

3. Verify whether the authority management Rbac microservice operation is successful 

Visit the background login page, enter the user name, password, verification code, and see if it is successful 

 

 Well, the client operation of the background user login function of the authority management Rbac microservice is completed. Here, the server and client functions of the microservice operation are roughly the same as [golang gin framework] Similarly, you can refer to this article for operation. The following section continues to explain the role addition, deletion, modification and query of the authority management Rbac microservice function

[Previous section] [golang gin framework] 40. Gin mall project - Captcha verification code microservice in microservice combat

[Next section] [golang gin framework] 42. Gin mall project - after the microservice actual combat background Rbac microservice role addition, deletion, modification and query microservice 

Guess you like

Origin blog.csdn.net/zhoupenghui168/article/details/131775296