using System;
using Microsoft.AspNetCore.Mvc;
using System.Text;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.Caching.AccressToken;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.WeChat.Service.HttpClients;
using CoreCms.Net.WeChat.Service.Enums;
using CoreCms.Net.WeChat.Service.Models;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using SKIT.FlurlHttpClient.Wechat.Api;
using LogLevel = NLog.LogLevel;
namespace CoreCms.Net.Web.Controllers.WeChat
{
///
/// 微信公众号用户授权事件
///
public class WeChatOffiaccountOAuth2Controller : ControllerBase
{
//private readonly string _weChatAppId = AppSettingsConstVars.WeiXinAppId;
//private readonly string _weChatSecret = AppSettingsConstVars.WeiXinAppSecret;
//private readonly string _weChatOAuth2CallBackUrl = AppSettingsConstVars.AppConfigAppInterFaceUrl + "/WeCharOAuth2/UserInfoCallback";
private readonly IWeChatApiHttpClientFactory _weChatApiHttpClientFactory;
private readonly IWeChatUserAccessTokenServices _weChatUserAccessTokenServices;
private readonly ICoreCmsUserWeChatInfoServices _weChatUserInfoServices;
///
/// 构造函数
///
public WeChatOffiaccountOAuth2Controller(IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IWeChatUserAccessTokenServices weChatUserAccessTokenServices, ICoreCmsUserWeChatInfoServices weChatUserInfoServices)
{
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
_weChatUserAccessTokenServices = weChatUserAccessTokenServices;
_weChatUserInfoServices = weChatUserInfoServices;
}
///
/// OAuthScope.snsapi_userinfo方式回调
///
///
///
///
///
[HttpGet]
public async Task UserInfoCallback(string code, string state, string bkUrl)
{
if (string.IsNullOrEmpty(code))
{
return Content("您拒绝了授权!");
}
//if (!state.Contains(","))
//{
// //这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下
// //实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证
// return Content("验证失败!请从正规途径进入!");
//}
var client = _weChatApiHttpClientFactory.CreateWeXinClient();
var accessToken = WeChatCacheAccessTokenHelper.GetWeChatAccessToken();
var request = new SnsOAuth2AccessTokenRequest()
{
AccessToken = accessToken,
Code = code
};
var response = await client.ExecuteSnsOAuth2AccessTokenAsync(request, HttpContext.RequestAborted);
if (response.ErrorCode != (int)WeChatReturnCode.ReturnCode.请求成功)
{
return Content("错误:" + response.ErrorMessage);
}
NLogUtil.WriteFileLog(LogLevel.Info, LogType.WeChat, "获取用户accessToken", JsonConvert.SerializeObject(response));
var accessTokenModel = await _weChatUserAccessTokenServices.QueryByClauseAsync(p => p.openid == response.OpenId);
if (accessTokenModel == null)
{
accessTokenModel = new WeChatUserAccessToken();
accessTokenModel.access_token = response.AccessToken;
accessTokenModel.expires_in = response.ExpiresIn;
accessTokenModel.openid = response.OpenId;
accessTokenModel.refresh_token = response.RefreshToken;
accessTokenModel.scope = response.Scope;
accessTokenModel.unionid = response.UnionId;
accessTokenModel.refresh_DateTime = DateTime.Now.AddSeconds(response.ExpiresIn);
await _weChatUserAccessTokenServices.InsertAsync(accessTokenModel);
}
else
{
accessTokenModel.access_token = response.AccessToken;
accessTokenModel.expires_in = response.ExpiresIn;
//accessTokenModel.openid = response.OpenId;
accessTokenModel.refresh_token = response.RefreshToken;
accessTokenModel.scope = response.Scope;
accessTokenModel.unionid = response.UnionId;
accessTokenModel.refresh_DateTime = DateTime.Now.AddSeconds(response.ExpiresIn);
await _weChatUserAccessTokenServices.UpdateAsync(accessTokenModel);
}
//因为第一步选择的是OAuthScope.snsapi_userinfo,这里可以进一步获取用户详细信息
try
{
var userInfoRequest = new SnsUserInfoRequest()
{
AccessToken = response.AccessToken,
OpenId = response.OpenId
};
var userInfoResponse = await client.ExecuteSnsUserInfoAsync(userInfoRequest, HttpContext.RequestAborted);
if (userInfoResponse.ErrorCode == (int)WeChatReturnCode.ReturnCode.请求成功)
{
var weChatUserInfo = await _weChatUserInfoServices.QueryByClauseAsync(p => p.openid == response.OpenId);
if (weChatUserInfo == null)
{
weChatUserInfo = new CoreCmsUserWeChatInfo()
{
createTime = DateTime.Now,
type = (int)GlobalEnumVars.UserAccountTypes.微信公众号,
//city = userInfoResponse.City,
//country = userInfoResponse.Country,
//province = userInfoResponse.Province,
nickName = userInfoResponse.Nickname,
//gender = userInfoResponse.Sex,
avatar = userInfoResponse.HeadImageUrl,
unionId = userInfoResponse.UnionId,
openid = userInfoResponse.OpenId,
gender = 1,
//isSubscribe = userInfoResponse.PrivilegeList,
};
var id = await _weChatUserInfoServices.InsertAsync(weChatUserInfo);
if (id > 0)
{
await _weChatUserInfoServices.UpdateAsync(
p => new CoreCmsUserWeChatInfo()
{
userId = id
}, p => p.id == id);
}
}
else
{
if (weChatUserInfo.nickName != userInfoResponse.Nickname || weChatUserInfo.avatar != userInfoResponse.HeadImageUrl || weChatUserInfo.unionId != userInfoResponse.UnionId)
{
weChatUserInfo.nickName = userInfoResponse.Nickname;
weChatUserInfo.avatar = userInfoResponse.HeadImageUrl;
weChatUserInfo.unionId = userInfoResponse.UnionId;
await _weChatUserInfoServices.UpdateAsync(weChatUserInfo);
}
}
}
else
{
return Content("错误:" + response.ErrorMessage);
}
var option = new CookieOptions
{
Expires = DateTime.Now.AddSeconds(1440)
};
Response.Cookies.Append(GlobalConstVars.CookieOpenId, userInfoResponse.OpenId, option);
if (!string.IsNullOrEmpty(bkUrl))
{
var outBase64String = Convert.FromBase64String(bkUrl);
var orgStr = Encoding.Default.GetString(outBase64String);
return Redirect(orgStr);
}
else
{
return Redirect(AppSettingsConstVars.AppConfigAppH5Url);
}
}
catch (Exception ex)
{
return Content(ex.Message);
}
}
}
}