JeffreySu / WeiXinMPSDK

微信全平台 .NET SDK, Senparc.Weixin for C#,支持 .NET Framework 及 .NET Core、.NET 8.0。已支持微信公众号、小程序、小游戏、微信支付、企业微信/企业号、开放平台、JSSDK、微信周边等全平台。 WeChat SDK for C#.
https://weixin.senparc.com
Apache License 2.0
8.4k stars 4.35k forks source link

UrlUtility.GenerateOAuthCallbackUrl问题 #1392

Closed teamssun closed 5 years ago

teamssun commented 6 years ago

问题描述 关于MVC使用UrlUtility.GenerateOAuthCallbackUrl问题 我的主机http://127.0.0.1:88反向代理解析到http://test.abc.cn后, 当使用[CustomOAuth(null, "/Account/OAuthCallback")]获取openid时,微信返回URI配置错误

分析: 用UrlUtility.GenerateOAuthCallbackUrl得到的网址是http://test.abc.cn:88 而urlData.Host、urlData.Port后台获取本地IIS主机名和端口,而非反向代理地址端口。

修改代码: Senparc.Weixin.HttpUtility.UrlUtility 82行 var returnUrl = $"{httpContext.Request.Url.Scheme}://{httpContext.Request.Headers["Host"]}{(httpContext.Request.Url.PathAndQuery)}";

Senparc.Weixin.HttpUtility.UrlUtility 85行 var host = httpContext.Request.Headers["Host"]; var port = string.IsNullOrEmpty(httpContext.Request.Headers["Port"])?80:httpContext.Request.Headers["Port"].ToInt() 测试mvc+.net45 望采纳更新到NuGet新版本,免得升级还重新编译Senparc.Weixin :)

JeffreySu commented 6 years ago

已经提交了,你看下是不是你要的效果: https://github.com/JeffreySu/WeiXinMPSDK/commit/f2c2f9805f98c8321d2f3f728f9573df77549208

(因为要考虑到更多的开发者环境,所以用了FormatWith)

nuget发布了预览版:https://www.nuget.org/packages/Senparc.Weixin.MP/16.2.1-preview1

欢迎反馈结果 😄

teamssun commented 6 years ago

谢谢,就是这个效果

teamssun commented 6 years ago

刚才访问正常是缓存我之前编译的dll,重启机子发现还是带着端口 &redirect_uri=http%3A%2F%2Fxxxx.nz.cn%3A88%2F 看不到源码反编译Senparc.Weixin.dll 6.0.3的还没有改过来

public static string GenerateOAuthCallbackUrl(HttpContextBase httpContext, string oauthCallbackUrl) { if (httpContext.Request.Url == null) {
throw new WeixinNullReferenceException("httpContext.Request.Url 不能为null!", httpContext.Request);
}
string url = httpContext.Request.Url.ToString(); Uri uri1 = httpContext.Request.Url;
string scheme = uri1.Scheme; string host = uri1.Host;
int port = uri1.Port;
string str4 = null;
string str5 = scheme.ToUpper();
if (((port == -1) || ((str5 == "HTTP") && (port == 80))) || ((str5 == "HTTPS") && (port == 0x1bb))) { str4 = ""; } else { str4 = ":" + port; } return $"{scheme}://{host}{str4}{oauthCallbackUrl}{(oauthCallbackUrl.Contains("?") ? "&" : "?")}returnUrl={url.UrlEncode()}"; }

teamssun commented 6 years ago

if NET35 || NET40 || NET45

。。。。。。。。。。。

        var urlData = httpContext.Request.Url;
        var scheme = urlData.Scheme;//协议
        var host = urlData.Host;//主机名(不带端口) //这行代码确实没改过来
        var port = urlData.Port;//端口      //这行代码确实没改过来
        string portSetting = null;//Url中的端口部分

。。。。。。。。。。。。

else

teamssun commented 6 years ago

刚才测试改了两行就好了

if NET35 || NET40 || NET45

var host = httpContext.Request.Headers["Host"]; var port = string.IsNullOrEmpty(httpContext.Request.Headers["Port"]) ? -1 : int.Parse(httpContext.Request.Headers["Port"]);

else

JeffreySu commented 6 years ago

刚才只改了MP,没有改Senparc.Weixin,其实我应该发布的是Senparc.Weixin.dll,稍等我重新发布一个

JeffreySu commented 6 years ago

另外还有一个需要探讨的问题,就是你这个例子里面是不需要带端口,但是如果遇到有端口的情况(SDK必须考虑到更多的情况),你提供的方法是不是也会强制把端口忽略掉?

JeffreySu commented 6 years ago

或者你直接修改了PR到Developer分支一下吧?我看着有点乱……

teamssun commented 6 years ago

对不起,给您添麻烦了 我的代理主机端口是80,故没出现问题。 调试发现Request.Headers["Port"]无效,标准请求没有此属性 获取访问主机名和端口都是通过Request.Headers["Host"]实现 当被访问主机端口是80时 Request.Headers["Host"]自动忽略80 当被访问主机端口非80时 Request.Headers["Host"]返回主机名和端口 1)http://test2.txz.cn/ Request.Headers["Host"] = http://test2.txz.cn 2)http://test2.txz.cn:888/ Request.Headers["Host"] = http://test2.txz.cn:888 有时间改吧

JeffreySu commented 6 years ago

@teamssun 你的想法是要怎么改,直接PR过来一下我看一下吧(到Developer分支)

JeffreySu commented 6 years ago

@teamssun 我先还原回去了,您直接PR一个最终的想法过来吧 🤝 https://github.com/JeffreySu/WeiXinMPSDK/commit/cc102c44eaa495cea6c40fe0779d971407508c82