这篇主要是承接上篇的网页授权获取用户基本信息的后文,也是对第一种静默授权之后,用户点击公众号内链接时,如何再次取得当前用户的openid的大致讲解和一些注意事项。
看过上一篇的小伙伴都知道,我们在用户关注的时候就已经将该用户的基本信息存入数据库中,那么如果该用户过了很久才点击公众号内的网页链接,那么我们该如何再次获取这个唯一标识呢?
重新获取openid
具体实现
首先,我们定一个获取openid的方法 regetopenid
public static void regetopenid() { string url = system.web.httpcontext.current.request.url.absoluteuri;//获取当前url if (system.web.httpcontext.current.session["openid"] == "" || system.web.httpcontext.current.session["openid"] == null) { //先要判断是否是获取code后跳转过来的 if (system.web.httpcontext.current.request.querystring["code"] == "" || system.web.httpcontext.current.request.querystring["code"] == null) { //code为空时,先获取code string getcodeurls = getcodeurl(url); system.web.httpcontext.current.response.redirect(getcodeurls);//先跳转到微信的服务器,取得code后会跳回来这页面的 } else { //code非空,已经获取了code后跳回来啦,现在重新获取openid log log = new log(appdomain.currentdomain.basedirectory + @"/log/log.txt"); string openid = ""; openid = getoauthaccessopenid(system.web.httpcontext.current.request.querystring["code"]);//重新取得用户的openid system.web.httpcontext.current.session["openid"] = openid; } } }
注:url最好是带域名的,花生壳的域名是行不通的,再调微信平台接口的时候,会报链接不正确错误
上文中getcodeurl方法如下
#region 重新获取code的跳转链接(没有用户授权的,只能获取基本信息) /// <summary>重新获取code,以后面实现带着code重新跳回目标页面(没有用户授权的,只能获取基本信息(openid))</summary> /// <param name="url">目标页面</param> /// <returns></returns> public static string getcodeurl(string url) { string codeurl = ""; //对url进行编码 url = system.web.httputility.urlencode(url); codeurl = string.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + url + "?action=viewtest&response_type=code&scope=snsapi_base&state=1#wechat_redirect"); return codeurl; } #endregion
上文中 getoauthaccessopenid方法如下
#region 以code换取用户的openid、access_token /// <summary>根据code获取用户的openid、access_token</summary> public static string getoauthaccessopenid(string code) { log log = new log(appdomain.currentdomain.basedirectory + @"/log/log.txt"); string openid = ""; string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code"; string gethtml = myhttphelper.httpget(url); log.log("拿到的url是:" + url); log.log("获取到的gethtml是" + gethtml); oauth_token ac = new oauth_token(); ac = jsonhelper.toobject<oauth_token>(gethtml); log.log("能否从html里拿到openid=" + ac.openid); openid = ac.openid; return openid; } #endregion
通过以上方法即可拿到用户的openid,如上文所示,用户id保存在system.web.httpcontext.current.session["openid"] 中,所以获取也是非常简单
在需要获取的地方执行
#region 获取当前用户openid regetopenid(); log.log("走完获取openid的方法之后,当前session的值是:" + system.web.httpcontext.current.session["openid"]); #endregion
注:上文中 oauth_token 类如下:
public class oauth_token { /// <summary> /// 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 /// </summary> public string access_token { get; set; } /// <summary> /// access_token接口调用凭证超时时间,单位(秒) /// </summary> public string expires_in { get; set; } /// <summary> /// 用户刷新access_token /// </summary> public string refresh_token { get; set; } /// <summary> /// 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的openid /// </summary> public string openid { get; set; } /// <summary> /// 用户授权作用域 /// </summary> public string scope { get; set; } }
日志文件
用到的简单日志类也顺便提供放上来:
/// <summary> /// 日志类 /// </summary> public class log { private string logfile; private streamwriter writer; private filestream filestream = null; public log(string filename) { logfile = filename; createdirectory(logfile); } public void log(string info) { try { system.io.fileinfo fileinfo = new system.io.fileinfo(logfile); if (!fileinfo.exists) { filestream = fileinfo.create(); writer = new streamwriter(filestream); } else { filestream = fileinfo.open(filemode.append, fileaccess.write); writer = new streamwriter(filestream); } writer.writeline(datetime.now + ": " + info); } finally { if (writer != null) { writer.close(); writer.dispose(); filestream.close(); filestream.dispose(); } } } public void createdirectory(string infopath) { directoryinfo directoryinfo = directory.getparent(infopath); if (!directoryinfo.exists) { directoryinfo.create(); } } }
调用呢,很简单,调用方法如下:
log log = new log(appdomain.currentdomain.basedirectory + @"/log/log.txt"); log.log("我会被输入在日志文件中")
最后呢,拿到当前用户openid,就可以从数据库再次获取到该用户的其他基本信息。从而可以更好的辅助你完成你项目中其他的业务模块。
