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);
}

浙公网安备 33010602011771号