DncZeus实战开源项目(一)基本流程

项目地址: https://gitee.com/rector/DncZeus

DncZeus 项目正常运行之坑

  • 坑1: 出现进程IDxxx无法运行的问题

    • 解决办法: 安装.NET 7框架
  • 坑2: launchSettings.json作如下配置

    {
        "$schema": "http://json.schemastore.org/launchsettings.json",
        "iisSettings": {
            "windowsAuthentication": false,
            "anonymousAuthentication": true,
            "iisExpress": {
                "applicationUrl": "http://localhost:5432",
                "sslPort": 0
            }
        },
        "profiles": {
          "IIS Express": {
            "commandName": "IISExpress",
            "launchBrowser": true,
            //"launchUrl": "api/values",
            "launchUrl": "swagger",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          },
          "DncZeus.Api": {
            "commandName": "Project",
            "launchBrowser": true,
            //"launchUrl": "api/values",
            "launchUrl": "swagger",
            "applicationUrl": "http://localhost:5432",
            "environmentVariables": {
              "ASPNETCORE_ENVIRONMENT": "Development"
            }
          }
        }
    }
    
  • 坑3: appsettings.json作如下配置

    {
        "AppSettings": {
            "Secret": "0123456789ABCDEF",
            "IsTrialVersion": false
        },
      "ConnectionStrings": {
        //"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=DncZeus;Trusted_Connection=True;MultipleActiveResultSets=true",
        "DefaultConnection": "Server=.;Database=DncZeus;Trusted_Connection=True;MultipleActiveResultSets=true;TrustServerCertificate=true;",
        "MySQLConnection": "Server=localhost;Database=dnczeus;Uid=root;Pwd=123456;",
        "PGSQLConnection": "Server=192.168.3.24;Database=dnczeus;Uid=postgres;Pwd=postgres;"
    
      },
        "Logging": {
            "IncludeScopes": false,
            "LogLevel": {
                "Default": "Warning"
            }
        },
        "Tokens": {
            "Key": "0123456789ABCDEF",
            "Issuer": "https://codedefault.com"
        },
        "AllowedHosts": "*",
        "AllowedOrigins": "http://localhost:9000",
        "DataProvider": "MSSQL" // 默认是MySQL,改成Sql Server
    }
    
  • 坑4: 默认的迁移文件是基于PostgreSQL语法的,如果改成MSSQL,需要删除所有迁移文件,重新使用MSSQL语法来迁移,否则会一直报SQL语法错误(即不能混用)!

实际项目流程分析

登录逻辑分析

  • 登录接口
- 请求网址: http://localhost:5432/api/oauth/auth?username=administrator&password=111111
- 请求方法: GET
- 响应成功示例: 
{
    "code": 200,
    "message": "操作成功",
    // 三段数据,前端通过算法解析出用户信息
    "data":  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6ImFkbWluaXN0cmF0b3IiLCJndWlkIjpbIjIwMjYzZGE0LWFlZDQtNGFiYS1hNmNjLWI5ODVjMDE2ODU4ZSIsIjIwMjYzZGE0LWFlZDQtNGFiYS1hNmNjLWI5ODVjMDE2ODU4ZSJdLCJhdmF0YXIiOiIiLCJkaXNwbGF5TmFtZSI6Iuezu-e7n-euoeeQhuWRmCIsImxvZ2luTmFtZSI6ImFkbWluaXN0cmF0b3IiLCJlbWFpbEFkZHJlc3MiOiIiLCJ1c2VyVHlwZSI6IjAiLCJuYmYiOjE3NjU4NjQ0NTIsImV4cCI6MTc2NjQ2OTI1MiwiaWF0IjoxNzY1ODY0NDUyfQ.u223tDv9f_IAa-nf3HskalqYlJVNpOVDsWIUcwq4_Kk"
}

- 响应失败示例:
{
  "code": 999,
  "message": "用户不存在",
  "data": null
}
  • 后端代码

using DncZeus.Api.Entities;
using DncZeus.Api.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using System.Linq;
using System.Security.Claims;
using DncZeus.Api.Auth;
using static DncZeus.Api.Entities.Enums.CommonEnum;

namespace DncZeus.Api.Controllers
{
    // 路由约定:使用 /api/oauth/auth 的清晰路由结构
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class OauthController : ControllerBase
    {
        private readonly AppAuthenticationSettings _appSettings;
        private readonly DncZeusDbContext _dbContext;
    
       
        public OauthController(IOptions<AppAuthenticationSettings> appSettings, DncZeusDbContext dbContext)
        {
        	// 通过 IOptions<T> 模式注入 JWT 配置,支持配置文件管理
            _appSettings = appSettings.Value;
            // 注入 EF Core 数据库上下文,用于用户数据查询
            _dbContext = dbContext;
        }

   
        [HttpGet]
        public IActionResult Auth(string username, string password)
        {
            var response = ResponseModelFactory.CreateInstance;
            DncUser user;
            using (_dbContext)
            {
                user = _dbContext.DncUser.FirstOrDefault(x => x.LoginName == username.Trim());
                if (user == null || user.IsDeleted == IsDeleted.Yes)
                {
                    response.SetFailed("用户不存在");
                    return Ok(response);
                }
                if (user.Password != password.Trim())
                {
                    response.SetFailed("密码不正确");
                    return Ok(response);
                }
                if (user.IsLocked == IsLocked.Locked)
                {
                    response.SetFailed("账号已被锁定");
                    return Ok(response);
                }
                if (user.Status == UserStatus.Forbidden)
                {
                    response.SetFailed("账号已被禁用");
                    return Ok(response);
                }
            }
            //  Claims 用户信息构建集
            var claimsIdentity = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, username),
                    new Claim("guid",user.Guid.ToString()),
                    new Claim("avatar",""),
                    new Claim("displayName",user.DisplayName),
                    new Claim("loginName",user.LoginName),
                    new Claim("emailAddress",""),
                    new Claim("guid",user.Guid.ToString()),
                    new Claim("userType",((int)user.UserType).ToString())
                });
            // 生成token
            var token = JwtBearerAuthenticationExtension.GetJwtAccessToken(_appSettings, claimsIdentity);
			
		   // 统一响应格式
            response.SetData(token);
            return Ok(response);
        }
    }
}

项目小补充--给swagger接口文档添加Authorize认证参数

// Startup.cs
......
 services.AddSwaggerGen(c =>
 {
     c.SwaggerDoc("v1", new OpenApiInfo { Title = "RBAC Management System API", Version = "v1" });
     ......
     c.IncludeXmlComments(xmlPath);

     // 添加 JWT 认证
     c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
     {
         Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
         Name = "Authorization",
         In = ParameterLocation.Header,
         Type = SecuritySchemeType.ApiKey,
         Scheme = "Bearer"
     });

     c.AddSecurityRequirement(new OpenApiSecurityRequirement()
     {
         {
             new OpenApiSecurityScheme
             {
                 Reference = new OpenApiReference
                 {
                     Type = ReferenceType.SecurityScheme,
                     Id = "Bearer"
                 }
             },
             Array.Empty<string>()
         }
     });
 });

获取用户个人信息Profile

  • 该接口包含用户信息菜单
- curl -X 'GET' \
  'http://localhost:5432/api/v1/account/profile' \
  -H 'accept: */*' \
  -H 'Authorization: Bearer xxx.yyy.zzz
  
- 响应成功示例: 

      {
      "code": 200,
      "message": "操作成功",
      "data": {
        "access": [],
        "avator": "https://file.iviewui.com/dist/a0e88e83800f138b94d2414621bd9704.png",
        "user_guid": "20263da4-aed4-4aba-a6cc-b985c016858e",
        "user_name": "系统管理员",
        "user_type": 0,
        "permissions": {
         ......
        }
       }

  • 后端接口
 public class AccountController : ControllerBase
 {
     private readonly DncZeusDbContext _dbContext;
     // 对象映射工具
     private readonly IMapper _mapper;
  
     public AccountController(DncZeusDbContext dbContext, IMapper mapper)
     {
         _dbContext = dbContext;
         _mapper = mapper;
     }
  
     [HttpGet]
     public IActionResult Profile()
     {
     	// 首先,创建响应对象
         var response = ResponseModelFactory.CreateInstance;
         using (_dbContext)
         {
         	// 用户身份验证
             var guid = AuthContextService.CurrentUser.Guid;
             var user = _dbContext.DncUser.FirstOrDefaultAsync(x => x.Guid == guid).Result;
			
			// 获取menus
             var menus = _dbContext.DncMenu.Where(x => x.IsDeleted == IsDeleted.No && x.Status == Status.Normal).ToList();

             var userGuid = AuthContextService.CurrentUser.Guid;
			
			// 权限查询和菜单查询
             var query = from rpm in _dbContext.DncRolePermissionMapping
                         join p in _dbContext.DncPermission on rpm.PermissionCode equals p.Code
                         join m in _dbContext.DncMenu on p.MenuGuid equals m.Guid
                         where p.IsDeleted == IsDeleted.No && p.Status == Status.Normal && _dbContext.DncUserRoleMapping
                             .Any(urm => urm.UserGuid == userGuid && urm.RoleCode == rpm.RoleCode)
                         select new DncPermissionWithMenu
                         {
                             PermissionCode = p.Code,
                             PermissionActionCode = p.ActionCode,
                             PermissionName = p.Name,
                             PermissionType = p.Type,
                             MenuName = m.Name,
                             MenuGuid = m.Guid,
                             MenuAlias = m.Alias,
                             IsDefaultRouter = m.IsDefaultRouter
                         };
			
			// 超管则直接获取所有权限
             if (AuthContextService.CurrentUser.IsSupperAdministrator)
             {
                 query = from p in _dbContext.DncPermission
                         join m in _dbContext.DncMenu on p.MenuGuid equals m.Guid
                         where p.IsDeleted == IsDeleted.No && p.Status == Status.Normal
                         select new DncPermissionWithMenu
                         {
                             PermissionCode = p.Code,
                             PermissionActionCode = p.ActionCode,
                             PermissionName = p.Name,
                             PermissionType = p.Type,
                             MenuName = m.Name,
                             MenuGuid = m.Guid,
                             MenuAlias = m.Alias,
                             IsDefaultRouter = m.IsDefaultRouter
                         };
             }


             var permissions = query.ToList();
			// 将权限按菜单分组返回
             var pagePermissions = permissions.GroupBy(x => x.MenuAlias).ToDictionary(g => g.Key, g => g.Select(x => x.PermissionActionCode).Distinct());
             // 构造响应数据并返回
             response.SetData(new
             {
                 access = new string[] { },
                 avator = user.Avatar,
                 user_guid = user.Guid,
                 user_name = user.DisplayName,
                 user_type = user.UserType,
                 permissions = pagePermissions

             });
         }
		
		
         return Ok(response);
     }
posted @ 2025-12-12 15:24  安_宁  阅读(13)  评论(0)    收藏  举报