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
|
{
|
/// <summary>
|
/// 微信公众号用户授权事件
|
/// </summary>
|
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;
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public WeChatOffiaccountOAuth2Controller(IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IWeChatUserAccessTokenServices weChatUserAccessTokenServices, ICoreCmsUserWeChatInfoServices weChatUserInfoServices)
|
{
|
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
|
_weChatUserAccessTokenServices = weChatUserAccessTokenServices;
|
_weChatUserInfoServices = weChatUserInfoServices;
|
}
|
|
/// <summary>
|
/// OAuthScope.snsapi_userinfo方式回调
|
/// </summary>
|
/// <param name="code"></param>
|
/// <param name="state"></param>
|
/// <param name="bkUrl"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public async Task<ActionResult> 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);
|
}
|
}
|
|
}
|
}
|