All checks were successful
continuous-integration/drone/push Build is passing
169 lines
6.0 KiB
C#
169 lines
6.0 KiB
C#
using CampusErrand.Data;
|
||
using CampusErrand.Models;
|
||
using CampusErrand.Models.Dtos;
|
||
using CampusErrand.Services;
|
||
using Microsoft.EntityFrameworkCore;
|
||
|
||
namespace CampusErrand.Endpoints;
|
||
|
||
public static class AuthEndpoints
|
||
{
|
||
public static void MapAuthEndpoints(this WebApplication app)
|
||
{
|
||
// 微信手机号登录接口
|
||
app.MapPost("/api/auth/login", async (
|
||
WeChatLoginRequest request,
|
||
IWeChatService weChatService,
|
||
JwtService jwtService,
|
||
AppDbContext db) =>
|
||
{
|
||
// 1. 调用微信 code2Session 获取 session_key 和 openid
|
||
var sessionResult = await weChatService.Code2SessionAsync(request.Code);
|
||
if (!sessionResult.Success)
|
||
{
|
||
return Results.BadRequest(new { code = 400, message = sessionResult.ErrorMessage });
|
||
}
|
||
|
||
// 2. 使用 session_key 解密手机号
|
||
string phoneNumber;
|
||
try
|
||
{
|
||
phoneNumber = weChatService.DecryptPhoneNumber(
|
||
sessionResult.SessionKey!, request.EncryptedData, request.Iv);
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return Results.BadRequest(new { code = 400, message = "手机号解密失败" });
|
||
}
|
||
|
||
// 3. 根据手机号查找或创建用户
|
||
var user = await db.Users.FirstOrDefaultAsync(u => u.Phone == phoneNumber);
|
||
if (user == null)
|
||
{
|
||
user = new User
|
||
{
|
||
OpenId = sessionResult.OpenId!,
|
||
Phone = phoneNumber,
|
||
Nickname = $"用户{phoneNumber[^4..]}",
|
||
CreatedAt = DateTime.UtcNow
|
||
};
|
||
db.Users.Add(user);
|
||
await db.SaveChangesAsync();
|
||
}
|
||
else if (string.IsNullOrEmpty(user.OpenId) && !string.IsNullOrEmpty(sessionResult.OpenId))
|
||
{
|
||
// 更新 OpenId(如果之前为空)
|
||
user.OpenId = sessionResult.OpenId;
|
||
await db.SaveChangesAsync();
|
||
}
|
||
|
||
// 4. 生成 JWT 返回
|
||
var token = jwtService.GenerateToken(user.Id, user.Role.ToString());
|
||
|
||
return Results.Ok(new LoginResponse
|
||
{
|
||
Token = token,
|
||
UserInfo = new UserInfo
|
||
{
|
||
Id = user.Id,
|
||
Phone = user.Phone,
|
||
Nickname = user.Nickname,
|
||
AvatarUrl = user.AvatarUrl,
|
||
Role = user.Role.ToString()
|
||
}
|
||
});
|
||
});
|
||
|
||
// 微信快捷登录(仅需 code,通过 openid 注册/登录)
|
||
app.MapPost("/api/auth/wx-login", async (
|
||
WxLoginRequest request,
|
||
IWeChatService weChatService,
|
||
JwtService jwtService,
|
||
AppDbContext db) =>
|
||
{
|
||
// 1. 调用微信 code2Session 获取 openid
|
||
Console.WriteLine($"[wx-login] 收到 code: {request.Code}");
|
||
var sessionResult = await weChatService.Code2SessionAsync(request.Code);
|
||
if (!sessionResult.Success)
|
||
{
|
||
return Results.BadRequest(new { code = 400, message = sessionResult.ErrorMessage });
|
||
}
|
||
|
||
// 2. 根据 openid 查找或创建用户
|
||
var openId = sessionResult.OpenId!;
|
||
var user = await db.Users.FirstOrDefaultAsync(u => u.OpenId == openId);
|
||
if (user == null)
|
||
{
|
||
// 自动注册,手机号暂时留空
|
||
var randomSuffix = Random.Shared.Next(1000, 9999).ToString();
|
||
user = new User
|
||
{
|
||
OpenId = openId,
|
||
Phone = "",
|
||
Nickname = $"微信用户{randomSuffix}",
|
||
CreatedAt = DateTime.UtcNow
|
||
};
|
||
db.Users.Add(user);
|
||
await db.SaveChangesAsync();
|
||
}
|
||
|
||
// 3. 生成 JWT 返回
|
||
var token = jwtService.GenerateToken(user.Id, user.Role.ToString());
|
||
|
||
return Results.Ok(new LoginResponse
|
||
{
|
||
Token = token,
|
||
UserInfo = new UserInfo
|
||
{
|
||
Id = user.Id,
|
||
Phone = user.Phone,
|
||
Nickname = user.Nickname,
|
||
AvatarUrl = user.AvatarUrl,
|
||
Role = user.Role.ToString()
|
||
}
|
||
});
|
||
});
|
||
|
||
// 受保护的测试端点(用于验证认证和授权)
|
||
app.MapGet("/api/protected", () => Results.Ok("ok"))
|
||
.RequireAuthorization();
|
||
|
||
// 管理员账号密码登录接口
|
||
app.MapPost("/api/admin/auth/login", async (
|
||
AdminLoginRequest request,
|
||
JwtService jwtService,
|
||
AppDbContext db,
|
||
IConfiguration configuration) =>
|
||
{
|
||
// 从配置读取管理员凭据
|
||
var adminUsername = configuration["Admin:Username"] ?? "admin";
|
||
var adminPassword = configuration["Admin:Password"] ?? "admin123";
|
||
|
||
if (request.Username != adminUsername || request.Password != adminPassword)
|
||
{
|
||
return Results.BadRequest(new { code = 400, message = "账号或密码错误" });
|
||
}
|
||
|
||
// 查找或创建管理员用户
|
||
var admin = await db.Users.FirstOrDefaultAsync(u => u.Role == UserRole.Admin);
|
||
if (admin == null)
|
||
{
|
||
admin = new User
|
||
{
|
||
OpenId = "admin",
|
||
Phone = "admin",
|
||
Nickname = "管理员",
|
||
Role = UserRole.Admin,
|
||
CreatedAt = DateTime.UtcNow
|
||
};
|
||
db.Users.Add(admin);
|
||
await db.SaveChangesAsync();
|
||
}
|
||
|
||
var token = jwtService.GenerateToken(admin.Id, admin.Role.ToString());
|
||
|
||
return Results.Ok(new { token });
|
||
});
|
||
}
|
||
}
|