campus-errand/server/Endpoints/AuthEndpoints.cs
18631081161 b359070a0e
All checks were successful
continuous-integration/drone/push Build is passing
聊天修改
2026-04-02 01:09:02 +08:00

202 lines
7.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using CampusErrand.Data;
using CampusErrand.Models;
using CampusErrand.Models.Dtos;
using CampusErrand.Services;
using CampusErrand.Helpers;
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
{
Uid = await BusinessHelpers.GenerateUniqueUid(db),
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,
Uid = user.Uid,
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
{
Uid = await BusinessHelpers.GenerateUniqueUid(db),
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,
Uid = user.Uid,
Phone = user.Phone,
Nickname = user.Nickname,
AvatarUrl = user.AvatarUrl,
Role = user.Role.ToString()
}
});
});
// 受保护的测试端点(用于验证认证和授权)
app.MapGet("/api/protected", () => Results.Ok("ok"))
.RequireAuthorization();
// 更新用户信息(昵称、头像)
app.MapPut("/api/user/profile", async (UpdateProfileRequest request, HttpContext httpContext, AppDbContext db) =>
{
var userIdClaim = httpContext.User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier);
if (userIdClaim == null) return Results.Unauthorized();
var userId = int.Parse(userIdClaim.Value);
var user = await db.Users.FindAsync(userId);
if (user == null) return Results.NotFound(new { code = 404, message = "用户不存在" });
if (!string.IsNullOrWhiteSpace(request.Nickname))
user.Nickname = request.Nickname.Trim();
if (!string.IsNullOrWhiteSpace(request.AvatarUrl))
user.AvatarUrl = request.AvatarUrl.Trim();
await db.SaveChangesAsync();
return Results.Ok(new UserInfo
{
Id = user.Id,
Uid = user.Uid,
Phone = user.Phone,
Nickname = user.Nickname,
AvatarUrl = user.AvatarUrl,
Role = user.Role.ToString()
});
}).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 });
});
}
}