69 lines
2.6 KiB
C#
69 lines
2.6 KiB
C#
using Microsoft.Extensions.Options;
|
|
using System.Net.Http.Json;
|
|
using System.Text.Json.Serialization;
|
|
using TakeoutSaaS.Application.Identity.Abstractions;
|
|
using TakeoutSaaS.Infrastructure.Identity.Options;
|
|
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
|
|
namespace TakeoutSaaS.Infrastructure.Identity.Services;
|
|
|
|
/// <summary>
|
|
/// 微信 code2Session 实现
|
|
/// </summary>
|
|
public sealed class WeChatAuthService(HttpClient httpClient, IOptions<WeChatMiniOptions> options) : IWeChatAuthService
|
|
{
|
|
private readonly WeChatMiniOptions _options = options.Value;
|
|
|
|
public async Task<WeChatSessionInfo> Code2SessionAsync(string code, CancellationToken cancellationToken = default)
|
|
{
|
|
var requestUri = $"sns/jscode2session?appid={Uri.EscapeDataString(_options.AppId)}&secret={Uri.EscapeDataString(_options.Secret)}&js_code={Uri.EscapeDataString(code)}&grant_type=authorization_code";
|
|
using var response = await httpClient.GetAsync(requestUri, cancellationToken);
|
|
response.EnsureSuccessStatusCode();
|
|
|
|
var payload = await response.Content.ReadFromJsonAsync<WeChatSessionResponse>(cancellationToken: cancellationToken);
|
|
if (payload == null)
|
|
{
|
|
throw new BusinessException(ErrorCodes.Unauthorized, "微信登录失败:响应为空");
|
|
}
|
|
|
|
if (payload.ErrorCode.HasValue && payload.ErrorCode.Value != 0)
|
|
{
|
|
var message = string.IsNullOrWhiteSpace(payload.ErrorMessage)
|
|
? $"微信登录失败,错误码:{payload.ErrorCode}"
|
|
: payload.ErrorMessage;
|
|
throw new BusinessException(ErrorCodes.Unauthorized, message);
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(payload.OpenId) || string.IsNullOrWhiteSpace(payload.SessionKey))
|
|
{
|
|
throw new BusinessException(ErrorCodes.Unauthorized, "微信登录失败:返回数据无效");
|
|
}
|
|
|
|
return new WeChatSessionInfo
|
|
{
|
|
OpenId = payload.OpenId,
|
|
UnionId = payload.UnionId,
|
|
SessionKey = payload.SessionKey
|
|
};
|
|
}
|
|
|
|
private sealed class WeChatSessionResponse
|
|
{
|
|
[JsonPropertyName("openid")]
|
|
public string? OpenId { get; set; }
|
|
|
|
[JsonPropertyName("unionid")]
|
|
public string? UnionId { get; set; }
|
|
|
|
[JsonPropertyName("session_key")]
|
|
public string? SessionKey { get; set; }
|
|
|
|
[JsonPropertyName("errcode")]
|
|
public int? ErrorCode { get; set; }
|
|
|
|
[JsonPropertyName("errmsg")]
|
|
public string? ErrorMessage { get; set; }
|
|
}
|
|
}
|