package middlewares import ( "git.sxidc.com/go-framework/baize/convenient/domain/auth/jwt_tools" "git.sxidc.com/go-framework/baize/convenient/domain/auth/permission" "git.sxidc.com/go-framework/baize/convenient/domain/auth/role" "git.sxidc.com/go-framework/baize/convenient/domain/auth/user" "git.sxidc.com/go-framework/baize/framework/binding" "git.sxidc.com/go-framework/baize/framework/core/api" "git.sxidc.com/go-framework/baize/framework/core/api/response" "git.sxidc.com/go-framework/baize/framework/core/domain" "git.sxidc.com/go-framework/baize/framework/core/domain/entity" "git.sxidc.com/go-framework/baize/framework/core/infrastructure" "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database" "git.sxidc.com/go-framework/baize/framework/core/infrastructure/database/sql" "github.com/dgrijalva/jwt-go/request" "github.com/pkg/errors" "net/http" ) func Authentication(dbSchema string, jwtSecretKey string) binding.Middleware { return func(c *api.Context, i *infrastructure.Infrastructure) { respFunc := response.SendMapResponse // 获取token token, err := request.AuthorizationHeaderExtractor.ExtractToken(c.Request) if err != nil { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) c.Abort() return } // 校验token valid, _, err := jwt_tools.CheckJWT(jwtSecretKey, token) if err != nil { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) c.Abort() return } if !valid { respFunc(c, http.StatusUnauthorized, nil, errors.New("无效token")) c.Abort() return } // 获取用户信息 dbExecutor := i.DBExecutor() // 查询用户 result, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: domain.TableName(dbSchema, &user.Entity{}), Conditions: sql.NewConditions().Equal(user.ColumnToken, token), }) if err != nil { if database.IsErrorDBRecordNotExist(err) { respFunc(c, http.StatusUnauthorized, nil, errors.New("token对应的用户不存在")) } else { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) } c.Abort() return } userInfo := new(user.Info) err = sql.ParseSqlResult(result, userInfo) if err != nil { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) c.Abort() return } // 获取用户的角色 roleIDResults, totalCount, err := database.Query(dbExecutor, &sql.QueryExecuteParams{ TableName: domain.RelationTableName(dbSchema, &user.Entity{}, &role.Entity{}), SelectClauses: []string{domain.RelationColumnName(&role.Entity{})}, Conditions: sql.NewConditions().Equal(domain.RelationColumnName(&user.Entity{}), userInfo.GetID()), PageNo: 0, PageSize: 0, }) if err != nil { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) c.Abort() return } if totalCount == 0 { respFunc(c, http.StatusUnauthorized, nil, errors.New("用户没有权限访问该资源: 没有分配角色")) c.Abort() return } roleIDs := make([]string, 0) err = sql.ParseSqlResult(roleIDResults, &roleIDs) if err != nil { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) c.Abort() return } // 查找权限 permissionIDResult, err := database.QueryOne(dbExecutor, &sql.QueryOneExecuteParams{ TableName: domain.TableName(dbSchema, &permission.Entity{}), SelectClauses: []string{entity.ColumnID}, Conditions: sql.NewConditions().Equal(permission.ColumnResource, c.FullPath()). Equal(permission.ColumnAction, c.Request.Method), }) if err != nil { if database.IsErrorDBRecordNotExist(err) { respFunc(c, http.StatusUnauthorized, nil, errors.New("用户没有权限访问该资源: 没有分配权限")) } else { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) } c.Abort() return } // 查询用户权限 permissionExist, err := database.CheckExist(dbExecutor, &sql.CheckExistExecuteParams{ TableName: domain.RelationTableName(dbSchema, &role.Entity{}, &permission.Entity{}), Conditions: sql.NewConditions().In(domain.RelationColumnName(&role.Entity{}), roleIDs). Equal(domain.RelationColumnName(&permission.Entity{}), permissionIDResult.ColumnValueString(entity.ColumnID)), }) if err != nil { respFunc(c, http.StatusUnauthorized, nil, errors.New(err.Error())) c.Abort() return } if !permissionExist { respFunc(c, http.StatusUnauthorized, nil, errors.New("用户没有权限访问该资源: 角色中没有该权限")) c.Abort() return } // 设置用户上下文 c.SetUserInfo(userInfo) c.Next() } }