2019-12-13 10:39:03 tianxiaojie_blog 阅读数 21
  • 港哥Elton自主开发的协程库解析

    Rust视频教程,该课程主要分享协程库的解析,由于Go语言在国内的风靡,许多开发者开始了解和关注使用协程(Coroutine)来实现高并发程序,Rust语言在比较早期的开发版本中也在标准库提供了协程的支持,但在后来的讨论中去掉了。协程也叫用户级线程、绿色线程、纤程,这些名字都体现了协程的一些特点:存在于用户空间,切换不需要进入到内核态,轻量。但是协程相对于传统的回调,侵入性很强,导致很难兼容那些并非为协程设计的第三方库。 演讲嘉宾:钟宇腾(Elton,GitHub、LinkedIn),香港大学计算机系毕业,微信游戏开发组工程师。

    6105 人正在学习 去看看 CSDN讲师

介绍

网页授权分两种 snsapi_basesnsapi_userinfo
snsapi_base 需要关注公众号才可以获取用户信息,但是用户无感
snsapi_userinfo 则不需要关注公众号,但需要用户确认是否被获取
这里以 snsapi_userinfo 为例实现获取用户信息

建立一个访问页面index.php

<?php
//scope=snsapi_userinfo实例
$appid='微信appid';
$redirect_uri = urlencode ( 'http://存放地址/getUserInfo.php' );
$url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appid&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
header("Location:".$url);

建立getUserInfo.php

<?php

$appid = "微信appid";
$secret = "微信secret";
$code = $_GET["code"];

//第一步:取得openid
$oauth2Url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=$appid&secret=$secret&code=$code&grant_type=authorization_code";
$oauth2 = getJson($oauth2Url);

//第二步:根据全局access_token和openid查询用户信息
$access_token = $oauth2["access_token"];
$openid = $oauth2['openid'];
$get_user_info_url = "https://api.weixin.qq.com/sns/userinfo?access_token=$access_token&openid=$openid&lang=zh_CN";
$userinfo = getJson($get_user_info_url);

//打印用户信息
print_r($userinfo);

function getJson($url){
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($ch);
    curl_close($ch);
    return json_decode($output, true);
}

访问

将两个文件直接放于服务器上,访问 index.php 地址即可

错误

access_token 非法 错误

解决方案参考

40001 无权限 错误

细察上面代码引用的
接口地址是
https://api.weixin.qq.com/sns/userinfo
而不是
https://api.weixin.qq.com/cgi-bin/user/info

获取用户信息思路

  1. 打开index.php页面跳转到getUserInfo.php页面
  2. 获取并存储用户信息,跳转到内容页面
    这么做是因为 网页授权获取用户信息 调用次数500 0000 次
    在这里插入图片描述

存储用户信息的思路

每次都进行建立连接,这样的实现方式是短链接,用完即关闭连接。因为mysql支持同一时间几千个连接数。而且我们的连接也没有到达一定量,不需要缓存实例或建立长连接

微信信息表结构

wx_OpenAndShare  
id,openid,nickname,phone,open,share,project,time
wx_Information
id,openid,nickname,sex,province,city,country,headimgurl,language,phone,privilege,unionid,project,time

在这里插入图片描述

2013-10-03 22:38:29 zhihang1103 阅读数 1098
  • 港哥Elton自主开发的协程库解析

    Rust视频教程,该课程主要分享协程库的解析,由于Go语言在国内的风靡,许多开发者开始了解和关注使用协程(Coroutine)来实现高并发程序,Rust语言在比较早期的开发版本中也在标准库提供了协程的支持,但在后来的讨论中去掉了。协程也叫用户级线程、绿色线程、纤程,这些名字都体现了协程的一些特点:存在于用户空间,切换不需要进入到内核态,轻量。但是协程相对于传统的回调,侵入性很强,导致很难兼容那些并非为协程设计的第三方库。 演讲嘉宾:钟宇腾(Elton,GitHub、LinkedIn),香港大学计算机系毕业,微信游戏开发组工程师。

    6105 人正在学习 去看看 CSDN讲师

    在微信接口的开发文档中定义了很多事件,当用户发送各种事件都有特定的回复,以下是关注时回复的具体代码展示:

<?php

//define your token
define("TOKEN", "wechatnow");
$wechatObj = new wechatCallbackapiTest();
//$wechatObj->valid();
$wechatObj->responseMsg();

class wechatCallbackapiTest
{
	public function valid()
    {
        $echoStr = $_GET["echostr"];

        //valid signature , option
        if($this->checkSignature()){
        	echo $echoStr;
        	exit;
        }
    }

    public function responseMsg()
    {
		//get post data, May be due to the different environments
		$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];

      	//extract post data
		if (!empty($postStr)){
                
              	$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
                $fromUsername = $postObj->FromUserName;
                $toUsername = $postObj->ToUserName;
                $keyword = trim($postObj->Content);
                $time = time();
                $textTpl = "<xml>
							<ToUserName><![CDATA[%s]]></ToUserName>
							<FromUserName><![CDATA[%s]]></FromUserName>
							<CreateTime>%s</CreateTime>
							<MsgType><![CDATA[%s]]></MsgType>
							<Content><![CDATA[%s]]></Content>
							<FuncFlag>0</FuncFlag>
							</xml>";  
							
				$ev=$postObj->Event;//subscirbe event			
				if($ev=="subscribe")
				{
					$msgType = "text";
					$contentStr="欢迎关注***,你的支持是我一直前行的动力!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
					echo $resultStr;
				}
				if($ev=="unsubscribe")
				{
					$msgType = "text";
					$contentStr="***将会推出更多贴心的功能,欢迎继续关注!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
					echo $resultStr;
				}
								
							           
				if(!empty( $keyword ))//depent on your keyword
                {
              		$msgType = "text";
                	switch ($keyword)
					{
					case "你好";
					$contentStr = "你好,我是robot!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;
					break;
					case "加油";
					$contentStr = "加油!";
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;
					break;
					case "图文";//返回图文信息
					$picTpl=" <xml>
					 <ToUserName><![CDATA[%s]]></ToUserName>
					 <FromUserName><![CDATA[%s]]></FromUserName>
					 <CreateTime>%s</CreateTime>
					 <MsgType><![CDATA[news]]></MsgType>
					 <ArticleCount>2</ArticleCount>
					 <Articles>
					 <item>
					 <Title><![CDATA[Hello Word!]]></Title> 
					 <Description><![CDATA[Weibo]]></Description>
					 <PicUrl><![CDATA[http://0.wechatnow.duapp.com/weibo.jpg]]></PicUrl>
					 <Url><![CDATA[http://weibo.com/***]]></Url>
					 </item>
					 <item>
					 <Title><![CDATA[wechat]]></Title>
					 <Description><![CDATA[***]]></Description>
					 <PicUrl><![CDATA[http://0.wechatnow.duapp.com/wechat.png]]></PicUrl>
					 <Url><![CDATA[http://weibo.com/***]]></Url>
					 </item>
					 </Articles>
					 </xml> 
					";
					$resultStr = sprintf($picTpl, $fromUsername, $toUsername, $time);
               	    echo $resultStr;
					default;
					$contentStr = "欢迎关注***,更多功能即将推出!";	
					$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
                	echo $resultStr;		
					}			
                }else{
                	echo "Input something...";
                }

        }else {
        	echo "";
        	exit;
        }
    }
		
	private function checkSignature()//check your signature
	{
        $signature = $_GET["signature"];
        $timestamp = $_GET["timestamp"];
        $nonce = $_GET["nonce"];	
        		
		$token = TOKEN;
		$tmpArr = array($token, $timestamp, $nonce);
		sort($tmpArr);
		$tmpStr = implode( $tmpArr );
		$tmpStr = sha1( $tmpStr );
		
		if( $tmpStr == $signature ){
			return true;
		}else{
			return false;
		}
	}
}

?>


2016-12-27 16:31:38 getluo 阅读数 1367
  • 港哥Elton自主开发的协程库解析

    Rust视频教程,该课程主要分享协程库的解析,由于Go语言在国内的风靡,许多开发者开始了解和关注使用协程(Coroutine)来实现高并发程序,Rust语言在比较早期的开发版本中也在标准库提供了协程的支持,但在后来的讨论中去掉了。协程也叫用户级线程、绿色线程、纤程,这些名字都体现了协程的一些特点:存在于用户空间,切换不需要进入到内核态,轻量。但是协程相对于传统的回调,侵入性很强,导致很难兼容那些并非为协程设计的第三方库。 演讲嘉宾:钟宇腾(Elton,GitHub、LinkedIn),香港大学计算机系毕业,微信游戏开发组工程师。

    6105 人正在学习 去看看 CSDN讲师

首先需要公众号有模板消息的权限,这里不多说明了。


要实现的功能就是在第三方网站通过调用接口在对给用户发消息,当然也可以给用户标签组群发消息。


获取access_token代码:

$weixin_appid = "";
$weixin_secret = "";
$weixin_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$weixin_appid."&secret=".$weixin_secret;
$weixin_return = get_url_contents ( $weixin_url );
$weixin = json_decode ( $weixin_return );
$access_token = $weixin->access_token;
//模板ID
$template_id = "";

发送消息代码:

				$dataarray = array(
						"touser"=>$openid,//用户的openid
						"template_id"=>$template_id,//消息模板id
						"url"=>$_POST['yanbao_url'],
						"data"=>array(
						    "first"=>array(
				                       "value"=>$_POST['yanbao_title'],
				                       "color"=>"#173177"
				                    ),
				                    "keyword1"=>array(
				                       "value"=>$_POST['yanbao_name'],
				                       "color"=>"#173177"
				                    ),
				                    "keyword2"=>array(
				                       "value"=>$_POST['yanbao_desc'],
				                       "color"=>"#173177"
				                    ),
				                    "remark"=>array(
				                       "value"=>$_POST['yanbao_more'],
				                       "color"=>"#173177"
				                    )
								)
				            );
				$data = json_encode($dataarray);
				$output = json_decode(do_post($url,$data));//do_post是模拟post的函数,请自行定义
				if($output->errcode == '0'){
					echo '<div class="updated"><p>发送成功!</p></div>';
				}else{
					echo '<div class="error"><p>发送失败!错误码:'.$output->errcode.'</p></div>';
				}

获取用户标签代码:

				<tr valign="top">
					<th scope="row"><label>用户标签</label></th>
					<td>
						<select name="yanbao_user_tag" id="yanbao_user_tag" style="min-width: 150px">
							<option value="">请选择</option>
							<option value="all">所有用户</option>
							<?php 
								$yanbao_user_tag_url = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=".$access_token;
								$yanbao_user_tag_return = get_url_contents ( $yanbao_user_tag_url );
								$yanbao_user_tag = json_decode ( $yanbao_user_tag_return );
								$tags = $yanbao_user_tag->tags;
								foreach ($tags as $tag) {
									echo '<option value="'.$tag->id.'">'.$tag->name.'('.$tag->count.')</option>';
								}
							?>		
						</select>
						<span class="description">(选择了用户标签就是<strong>群发</strong>给该标签下的用户)</span>
					</td>
				</tr>

获取用户代码:

<tr valign="top">
					<th scope="row"><label>用户</label></th>
					<td>
						<select name="yanbao_user" id="yanbao_user">
							<option selected="selected" value="">请选择</option>
							<?php 
								/*
								$yanbao_user_url = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=".$access_token."&next_openid=";
								$yanbao_user_return = get_url_contents ( $yanbao_user_url );
								$yanbao_user = json_decode ( $yanbao_user_return );
								$openids = $yanbao_user->data->openid;
								foreach ($openids as $openid) {
									$added_user = Moge_check_weixin_user_added($openid);
									if($added_user){
										echo '<option value="'.$openid.'">'.$added_user->nickname.'</option>';
									}else{
										$user = Moge_weixin_get_user_info($access_token,$openid);
										$wpdb->query("insert into ".$wpdb->prefix."erphp_weixin_users (openid,nickname) values('".$openid."','".$user->nickname."')");
										echo '<option value="'.$openid.'">'.$user->nickname.'</option>';
									}
								}*/
								
								$weixin_users = Moge_get_weixin_users();//获取本地数据库里的微信用户函数
								if($weixin_users){
									foreach ($weixin_users as $user) {
										echo '<option value="'.$user->openid.'">'.$user->nickname.'</option>';
									}
								}
								
							?>
						</select>
						<span class="description">(若已选择了用户标签,此项选择就无效了。)</span>
					</td>
				</tr>


这里主要遇到一个问题就是如果高效快速的获取用户列表的昵称(nickname),通过以下的接口

https://api.weixin.qq.com/cgi-bin/user/get?access_token=ACCESS_TOKEN&next_openid=NEXT_OPENID

只能获取用户的openid,我尝试过针对每个用户获取其详细资料,结果页面直接卡死了(用户数量太多)。虽然看到有批量获取资料,但是不适合用,最后没办法,只能先循环获取然后存在本地数据库,定期获取更新下数据库了,有个弊端就是取消关注的人还是会在本地数据库里。

2018-09-12 22:05:40 weixin_41031687 阅读数 328
  • 港哥Elton自主开发的协程库解析

    Rust视频教程,该课程主要分享协程库的解析,由于Go语言在国内的风靡,许多开发者开始了解和关注使用协程(Coroutine)来实现高并发程序,Rust语言在比较早期的开发版本中也在标准库提供了协程的支持,但在后来的讨论中去掉了。协程也叫用户级线程、绿色线程、纤程,这些名字都体现了协程的一些特点:存在于用户空间,切换不需要进入到内核态,轻量。但是协程相对于传统的回调,侵入性很强,导致很难兼容那些并非为协程设计的第三方库。 演讲嘉宾:钟宇腾(Elton,GitHub、LinkedIn),香港大学计算机系毕业,微信游戏开发组工程师。

    6105 人正在学习 去看看 CSDN讲师

设置好微信公众平台与服务器信息以后就可以获取用户对公众号的操作信息直接上PHP代码:

             $postStr = @$GLOBALS["HTTP_RAW_POST_DATA"];            
              // 获取用户信息
              $postObj = @simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
              @$fromUsername = $postObj->FromUserName;//谁发的(用户openid)
              @$toUsername = $postObj->ToUserName; //发送给谁(公众号id)
              @$createtime = $postObj->CreateTime; //发送时间
                //首次关注定义变量
                $type = $postObj->MsgType;
                $cus = $postObj->Event;
                $EventKey = trim((string)$postObj->EventKey);
                $keyArray = explode("_", $EventKey);
               @$content = $postObj->Content; //获取用户发送文本   

          if($type=="event" and $cus=="subscribe"){//判断用户首次关注事件

                     //写自己需要执行的程序。  

              }else if($type=="event" and $cus=="unsubscribe"){//判断用户取消关注事件   

                     //写自己需要执行的程序。    

              }
2016-01-14 13:55:49 HinstenyHisoka 阅读数 5962
  • 港哥Elton自主开发的协程库解析

    Rust视频教程,该课程主要分享协程库的解析,由于Go语言在国内的风靡,许多开发者开始了解和关注使用协程(Coroutine)来实现高并发程序,Rust语言在比较早期的开发版本中也在标准库提供了协程的支持,但在后来的讨论中去掉了。协程也叫用户级线程、绿色线程、纤程,这些名字都体现了协程的一些特点:存在于用户空间,切换不需要进入到内核态,轻量。但是协程相对于传统的回调,侵入性很强,导致很难兼容那些并非为协程设计的第三方库。 演讲嘉宾:钟宇腾(Elton,GitHub、LinkedIn),香港大学计算机系毕业,微信游戏开发组工程师。

    6105 人正在学习 去看看 CSDN讲师

当我们进行微信平台相关内容开发时,如果想做一些针对微信用户进行一些信息获取及消息推送,那我们第一步先要拿到微信用户的OPENID(用户唯一标识,建立在一个公众号与一个微信用户之间,即针对一个公众号,所有的微信用户都享有一个独立不变的标识);


1 . 如果微信用户已经关注自己的公众号, 那可以通过微信接口里面的用户管理模板直接获取到对应公众号的所有已关注用户OPENID的列表;
1). 在调用所有的微信接口之前,我们先要请求授权,拿到access_token

    @Getter
    @Config("wechat.appid")
    private static String WECHATAPPID;

    @Getter
    @Config("wechat.appsecret")
    private static String WECHATAPPSECRET;

    public static final String ACCESS_TOKEN = "access_token";
    public final static String WECHATACCESSTOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=";
        /**
     * <p>
     * 成功: {"access_token":"ACCESS_TOKEN","expires_in":7200}
     * </p>
     * <p>
     * 失败: {"errcode":40013,"errmsg":"invalid appid"}
     * </p>
     * @return 如果没有获取到有效的凭据,就返回 null
     */
    private static Map getWechatAPPAccessTokenFromWeChat() {
        StringBuilder accessTokenUrl = new StringBuilder().append(WECHATACCESSTOKEN).append(WECHATAPPID)
                        .append("&secret=").append(WECHATAPPSECRET);
        Map result = HttpClientUtil.readHttpContent(accessTokenUrl.toString());
        if (result != null && result.get(ACCESS_TOKEN) != null)
            return result;
        return null;
    }

    //HttpClientUtil.class static method
    /**
     * get json content and transform to Map from the urlStr
     * If occuer one error just return null.
     * @param urlStr
     * @return
     */
    public static Map<String,Object> readHttpContent(String urlStr){
        Map<String, Object> result = null;
        HttpEntity httpEntity = null;
        try {
            HttpResponse response = Request.Get(urlStr).execute().returnResponse();
            httpEntity = response.getEntity();
        }catch (IOException e) {
            logger.error("Get resouse from {} had occurred an error: {}", urlStr, e.toString());
            return result;
        }
        try (
            InputStream in = httpEntity.getContent();
        ){
            ObjectMapper mapper = new ObjectMapper();
            result = mapper.readValue(in, HashMap.class);
        }catch (IOException e) {
            logger.error("Get json content from {} had occurred an error: {}", urlStr, e.toString());
            return result;
        }
        return result;
    }

2). 使用前面得到的access_token获取公众号的微信关注用户列表

    public static final String ERRMSG = "errmsg";
    public final static String WECHATUSERLISTURL = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=";
    /**
     *<p>
     * 获取成功:{
     *  "total":23000,
     *  "count":10000,
     *  "data":{"
     *    openid":[
     *      "OPENID1",
     *      "OPENID2",
     *      ...,
     *      "OPENID10000"
     *    ]
     *  },
     *  "next_openid":"OPENID10000"
     *  }
     *</p>
     *
     *<p>
     * 获取失败:{"errcode":40013,"errmsg":"invalid appid"}
     *</p>
     *
     *
     * 获取微信公众帐号的关注者列表(wechat user openID),每次最多10000个
     *
     * @param accessToken
     * @param next_openid: 没有此参数,则默认从关注列表的第一个开始获取
     * @return
     */
    public static Map getWechatUserOpenIDList(String accessToken, String next_openid) {
        StringBuilder urlB = new StringBuilder().append(WECHATUSERLISTURL).append(accessToken);
        if (!Strings.isBlank(next_openid))
            urlB.append("&next_openid=").append(next_openid);
        Map result = HttpClientUtil.readHttpContent(urlB.toString());
        if (result != null && result.get(ERRMSG) == null)
            return result;
        return null;
    }
采用方法一,到此便得到了用户openID列表,可以进行后面获取微信用户信息及向用户推送模板消息等;

2 . 无论微信用户是否关注自己的公众号, 当微信用户访问我们的web站点时(通过微信内置浏览器),我们可以通过页面授权的方式拿到微信用户的OpendID(页面授权需要跳转到微信服务器拿到oauth_code然后再换取access_token及OpendID);
1). 为我们的web站点服务添加一个filter,拦截来自微信浏览器的请求,进行302跳转到微信站点,拿到授权码再回调回来;

public class WechatFilter implements Filter {

    private static final Logger logger             = LoggerFactory.getLogger(WechatFilter.class);

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        if (response.isCommitted()) {
            chain.doFilter(request, response);
            return;
        }
        //判断请求是否来自微信浏览器
        if (!WebUtil.isWechatRequest(httpRequest)) {
            chain.doFilter(request, response);
            return;
        }
        String requestURL = WebUtil.getRequsetUrl(httpRequest, true, true);
        logger.debug("Request from wechat client:{}", requestURL);
        HttpSession session = httpRequest.getSession();
        String weChatOpenId = (String) session.getAttribute(WeChatManager.WECHATOPENID);
        if (weChatOpenId == null) {
            if (httpRequest.getParameter(WeChatManager.CODE) == null) {
                StringBuilder url = new StringBuilder("http://").append(WebUtil.getRequsetUrl(httpRequest, true, true));
                response.reset();
                ((HttpServletResponse) response).sendRedirect(url.toString());
                return;
            } else {
                String oauthCode = httpRequest.getParameter(WeChatManager.CODE);
                if (!Strings.isBlank(oauthCode)) {
                    Map<String, Object> oauth_data = WeChatPageInterface.getWechatPageAccessToken(oauthCode);
                    weChatOpenId = oauthCode != null && oauth_data.get(WeChatManager.OPENID) != null ? (String) oauth_data.get(WeChatManager.OPENID) : null;
                    session.setAttribute(WeChatManager.WECHATOPENID, weChatOpenId);
                } else {
                    logger.warn("The oauth_code is empty!");
                }
            }
        }
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

}
    //WeChatPageInterface.class static method
    /**
     * <p>
     * 微信获取授权成功:{ "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN",
     * "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" }
     * </p>
     * <p>
     * 微信获取授权失败:{"errcode":40029,"errmsg":"invalid code"}
     * </p>
     *
     * 请求微信公众号的网页授权,得到用户OpenID和access_token
     * 微信网页授权是通过OAuth2.0机制实现的,在用户授权给公众号后,公众号可以获取到一个网页授权特有的接口调用凭证( 网页授权access_token),
     * 通过网页授权access_token可以进行授权后接口调用,如获取用户基本信息;
     *
     * @return 如果没有获取到有效的凭据,就返回 null
     */
    public static Map<String, Object> getWechatPageAccessToken(String oauthCode) {
        StringBuilder accessTokenUrl = new StringBuilder().append(WeChatManager.weChatAuthAccessTokenPage).append(WeChatManager.getWECHATAPPID())
                        .append("&secret=").append(WeChatManager.getWECHATAPPSECRET()).append("&code=")
                        .append(oauthCode).append("&grant_type=").append("authorization_code");
        Map<String, Object> accessToken = HttpClientUtil.readHttpContent(accessTokenUrl.toString());
        if (accessToken != null && accessToken.get(WeChatManager.ACCESS_TOKEN) != null) {
            return accessToken;
        }
        return null;
    }

至此,我们通过两种方式都可以获取微信用户的OpenID了,至于采用哪一种可以根据实际业务环境;

PS: OpenID是介于微信用户与公众账号之间恒定不变的,所以可以进行三方持久化存储;

没有更多推荐了,返回首页