拉取用户信息(需scope为 snsapi_userinfo)
@param access_token access_token
@param openid openid
@param lang 国家地区语言版本，zh_CN 简体，zh_TW 繁体，en 英语
@return User
968651
public static User userinfo(String access_token,String openid,String lang){
		return userinfo(access_token, openid, lang,0);
	}
673817
public function vaildAccessToken(string $access_token, string $open_id)
    {
        $data = [
            'access_token' => $access_token,
            'openid' => $open_id,
        ];
        $url = self::WECHAT.'auth?'.http_build_query($data);
        $data = $this->curl->get($url);

        return Response::json($data);
    }
348385
public static BaseResult auth(String access_token,String openid){
		HttpUriRequest httpUriRequest = RequestBuilder.get()
				.setUri(BASE_URI + "/sns/auth")
				.addParameter(PARAM_ACCESS_TOKEN, API.accessToken(access_token))
				.addParameter("openid", openid)
				.build();
		return LocalHttpClient.executeJsonResult(httpUriRequest,BaseResult.class);
	}
745983
static String getAccessTokenForUserId(String userId) {
        if (userId == null && getUserId() == null
                || userId != null && userId.equals(getUserId())) {
            return getAccessToken();
        } else {
            JSONObject usersArchive = getJSONObject(PER_USER_ARCHIVE_PREF_NAME);
            if (usersArchive == null) usersArchive = new JSONObject();
            JSONObject userArchive = usersArchive.optJSONObject(userId == null ? "" : userId);
            if (userArchive == null) userArchive = new JSONObject();
            return JSONUtil.optString(userArchive, ACCESS_TOKEN_PREF_NAME);
        }
    }
1242978
protected static function userinfo_uri($access_token, $openid, $lang = 'zh_CN')
    {
        $param = [
            'access_token' => $access_token,
            'openid' => $openid,
            'lang' => $lang,
        ];

        return self::USERINFO_URI . http_build_query($param);
    }
1160231
public static BaseResult userInfoUpdateremark(String access_token,String openid,String remark){
		String postJson = String.format("{\"openid\":\"%1$s\",\"remark\":\"%2$s\"}", openid,remark);
		HttpUriRequest httpUriRequest = RequestBuilder.post()
										.setHeader(jsonHeader)
										.setUri(BASE_URI+"/cgi-bin/user/info/updateremark")
										.addParameter(PARAM_ACCESS_TOKEN, API.accessToken(access_token))
										.setEntity(new StringEntity(postJson,Charset.forName("utf-8")))
										.build();
		return LocalHttpClient.executeJsonResult(httpUriRequest,BaseResult.class);
	}
464861
public function isAttention($openid = '') {
        try {
            $access_token = $this->getAccessToken();
            #设置URL地址
            $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$access_token&openid=$openid&lang=zh_CN";
            #提交数据
            $res = to_array($this->httpGet($url));
            if (isset($res['subscribe'])) {
                return $res;
            } else {
                throw new Exception($res['errmsg'], $res['errcode']);
            }
        } catch (Exception $e) {
            debug::exception($e);
        }
    }
284846
public RetResult<String> getMPOpenidByCode(String code) throws IOException {
        if (code != null) code = code.replace("\"", "").replace("'", "");
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + appid + "&secret=" + appsecret + "&code=" + code + "&grant_type=authorization_code";
        String json = getHttpContent(url);
        if (finest) logger.finest(url + "--->" + json);
        Map<String, String> jsonmap = convert.convertFrom(TYPE_MAP_STRING_STRING, json);
        return new RetResult<>(jsonmap.get("openid"));
    }
1319148
public GetUsersResponse getUsers(String nextOpenid) {
        GetUsersResponse response;
        LOG.debug("获取关注者列表.....");
        String url = BASE_API_URL + "cgi-bin/user/get?access_token=#";
        if (StrUtil.isNotBlank(nextOpenid)) {
            url += "&next_openid=" + nextOpenid;
        }
        BaseResponse r = executeGet(url);
        String resultJson = isSuccess(r.getErrcode()) ? r.getErrmsg() : r.toJsonString();
        response = JSONUtil.toBean(resultJson, GetUsersResponse.class);
        return response;
    }
457518
def query_auth(self, authorization_code):
        
        result = self._query_auth(authorization_code)

        assert result is not None \
            and 'authorization_info' in result \
            and 'authorizer_appid' in result['authorization_info']

        authorizer_appid = result['authorization_info']['authorizer_appid']
        if 'authorizer_access_token' in result['authorization_info'] \
                and result['authorization_info']['authorizer_access_token']:
            access_token = result['authorization_info']['authorizer_access_token']
            access_token_key = '{0}_access_token'.format(authorizer_appid)
            expires_in = 7200
            if 'expires_in' in result['authorization_info']:
                expires_in = result['authorization_info']['expires_in']
            self.session.set(access_token_key, access_token, expires_in)
        if 'authorizer_refresh_token' in result['authorization_info'] \
                and result['authorization_info']['authorizer_refresh_token']:
            refresh_token = result['authorization_info']['authorizer_refresh_token']
            refresh_token_key = '{0}_refresh_token'.format(authorizer_appid)
            self.session.set(refresh_token_key, refresh_token)  # refresh_token 需要永久储存，不建议使用内存储存，否则每次重启服务需要重新扫码授权
        return result
163886
function XingeApp(accessId, secretKey){

	//效验accessId是否为整形
	if(parseInt(accessId) !== accessId){
		throw new Error('accessId is invalid');
	}

	//效验secretKey是否为非空字符串
	if(typeof secretKey !== 'string' || secretKey.trim().length === 0){
		throw new Error('secretKey is invalid');
	}else{
		secretKey = secretKey.trim();
	}

	this.accessId  = accessId;
	this.secretKey = secretKey;

	/**
	 * 推送消息给单个设备
	 * @param {string}   deviceToken           设备token
	 * @param {Message}  message               推送的消息
     * @param {int}      environment           向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境。Android可不填。
	 * @param {Function} callback(err, result) 回调函数
	 */
	this.pushToSingleDevice = function(deviceToken, message, environment, callback){

		//效验deviceToken合法性
        deviceToken += '';
        deviceToken = deviceToken.trim();
		if(deviceToken.length === 0){
			throw new Error('deviceToken is invalid');
		}

		//效验message合法性
		if(!(message instanceof AndroidMessage) && !(message instanceof IOSMessage)){
			throw new Error('message is invalid');
		}

        //校验environment合法性
        if(message instanceof IOSMessage && environment !== exports.IOS_ENV_PRO && environment !== exports.IOS_ENV_DEV){
            throw new Error('environment is invalid');
        }

        if(message instanceof AndroidMessage && arguments.length === 3){
            callback = arguments[2];
        }

		//构造请求参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			expire_time: message.expireTime,
			send_time: message.formatSendTime(),
			device_token: deviceToken,
			message: message.format()
		};

        //如果是Android平台,添加multi_pkg参数;如果是iOS平台，添加environment参数
        if(message instanceof AndroidMessage){
            params.message_type = message.type;
            params.multi_pkg = message.multiPkg;
        }else{
            params.message_type = 0;
            params.environment = environment;
        }

		//调用API
		callAPI(API_PUSH_TO_SINGLE_DEVICE, params, "POST", 10000, this.secretKey, callback);
	};

	/**
	 * 推送消息给单个账户或别名
	 * @param {string}   account               账户或别名
	 * @param {Message}  message               推送的消息
     * @param {int}      environment           向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境。Android可不填
	 * @param {Function} callback(err, result) 回调函数
     */
	this.pushToSingleAccount = function(account, message, environment, callback){

		//效验account是否为非空字符串
        account += '';
        account = account.trim();
		if(account.length === 0){
			throw new Error('account is invalid');
		}

		//效验message
		if(!(message instanceof AndroidMessage) && !(message instanceof IOSMessage)){
			throw new Error('message is invalid');
		}

        //校验environment合法性
        if(message instanceof IOSMessage && environment !== exports.IOS_ENV_PRO && environment !== exports.IOS_ENV_DEV){
            throw new Error('environment is invalid');
        }

        if(message instanceof AndroidMessage && arguments.length === 3){
            callback = arguments[2];
        }

		//构造请求参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			expire_time: message.expireTime,
			send_time: message.formatSendTime(),
			account: account,
			message: message.format()
		};

        //如果是Android平台,添加multi_pkg参数;如果是iOS平台，添加environment参数
        if(message instanceof AndroidMessage){
            params.message_type = message.type;
            params.multi_pkg = message.multiPkg;
        }else{
            params.message_type = 0;
            params.environment = environment;
        }

		//调用API
		callAPI(API_PUSH_TO_SINGLE_ACCOUNT, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 推送消息给批量账号
	 * @param {array}    accounts    账号数组
	 * @param {Message}  message     推送的消息
	 * @param {int}      environment 向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境。Android可不填
	 * @param {Function} callback    回调函数
	 */
	this.pushByAccounts = function(accounts, message, environment, callback){

		//效验accounts
		if(!util.isArray(accounts) || accounts.length === 0){
			throw new Error('accounts is invalid');
		}else{
			for(var i=0; i < accounts.length; i++){
				accounts[i] += '';
				accounts[i] = accounts[i].trim();
				if(accounts[i].length === 0){
					throw new Error('accounts is invalid');
				}
			}
		}

		//效验message
		if(!(message instanceof AndroidMessage) && !(message instanceof IOSMessage)){
			throw new Error('message is invalid');
		}

		//校验environment
		if(message instanceof IOSMessage && environment !== exports.IOS_ENV_PRO && environment !== exports.IOS_ENV_DEV){
			throw new Error('environment is invalid');
		}

		if(message instanceof AndroidMessage && arguments.length === 3){
			callback = arguments[2];
		}

		//构造请求参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			expire_time: message.expireTime,
			account_list: JSON.stringify(accounts),
			message: message.format()
		};

		//如果是Android平台,添加multi_pkg参数;如果是iOS平台，添加environment参数
		if(message instanceof AndroidMessage){
			params.message_type = message.type;
			params.multi_pkg = message.multiPkg;
		}else{
			params.message_type = 0;
			params.environment = environment;
		}

		//调用API
		callAPI(API_PUSH_BY_ACCOUNTS, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 推送消息到所有设备
	 * @param {Message}  message               推送的消息
     * @param {int}      environment           向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境。Android可不填
	 * @param {Function} callback(err, result) 回调函数
     */
	this.pushToAllDevices = function(message, environment, callback){

		//效验message
		if(!(message instanceof AndroidMessage) && !(message instanceof IOSMessage)){
			throw new Error('message is invalid');
		}

        //校验environment
        if(message instanceof IOSMessage && environment !== exports.IOS_ENV_PRO && environment !== exports.IOS_ENV_DEV){
            throw new Error('environment is invalid');
        }

        if(message instanceof AndroidMessage && arguments.length === 2){
            callback = arguments[1];
        }

		//构造请求参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			expire_time: message.expireTime,
			send_time: message.formatSendTime(),
			message: message.format()
		};

        //重复推送
        if(parseInt(message.loopTimes) == message.loopTimes && parseInt(message.loopInterval) == message.loopInterval){
            params.loop_times    = parseInt(message.loopTimes);
            params.loop_interval = parseInt(message.loopInterval);
        }

        //如果是Android平台,添加multi_pkg参数;如果是iOS平台，添加environment参数
        if(message instanceof AndroidMessage){
            params.message_type = message.type;
            params.multi_pkg = message.multiPkg;
        }else{
            params.message_type = 0;
            params.environment = environment;
        }

		//调用API
		callAPI(API_PUSH_TO_ALL_DEVICES, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 根据指定的tag推送消息
	 * @param {array}    tags                  指定推送目标的tag列表，每个tag是一个string
	 * @param {string}   tagOperation          多个tag的运算关系，取值为AND或OR
	 * @param {Message}  message               推送的消息
     * @param {int}      environment           向iOS设备推送时必填，1表示推送生产环境；2表示推送开发环境。Android可不填
	 * @param {Function} callback(err, result) 回调函数
     */
	this.pushByTags = function(tags, tagOperation, message, environment, callback){

		//效验tags
		if(!util.isArray(tags) || tags.length === 0){
			throw new Error('tags is invalid');
		}else{
			for(var i=0; i < tags.length; i++){
                tags[i] += '';
                tags[i] = tags[i].trim();
				if(tags[i].length === 0){
					throw new Error('tags is invalid');
				}
			}
		}

		//效验tagOperation
		if(tagOperation !== exports.TAG_OPERATION_AND && tagOperation !== exports.TAG_OPERATION_OR){
			throw new Error('tagOperation is invalid');
		}

        //效验message
        if(!(message instanceof AndroidMessage) && !(message instanceof IOSMessage)){
            throw new Error('message is invalid');
        }

        //校验environment
        if(message instanceof IOSMessage && environment !== exports.IOS_ENV_PRO && environment !== exports.IOS_ENV_DEV){
            throw new Error('environment is invalid');
        }

        if(message instanceof AndroidMessage && arguments.length === 4){
            callback = arguments[3];
        }

		//构造请求参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			expire_time: message.expireTime,
			send_time: message.formatSendTime(),
			tags_list: JSON.stringify(tags),
			tags_op: tagOperation,
			message: message.format()
		};

        //重复推送
        if(parseInt(message.loopTimes) == message.loopTimes && parseInt(message.loopInterval) == message.loopInterval){
            params.loop_times    = parseInt(message.loopTimes);
            params.loop_interval = parseInt(message.loopInterval);
        }

        //如果是Android平台,添加multi_pkg参数;如果是iOS平台，添加environment参数
        if(message instanceof AndroidMessage){
            params.message_type = message.type;
            params.multi_pkg = message.multiPkg;
        }else{
            params.message_type = 0;
            params.environment = environment;
        }

		//调用API
		callAPI(API_PUSH_BY_TAGS, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 批量查询推送状态
	 * @param {array}    pushIds               推送id数组
	 * @param {Function} callback(err, result) 回调函数
	 */
	this.queryPushStatus = function(pushIds, callback){

		var arrPushIds = [];

		if(!util.isArray(pushIds) || pushIds.length === 0){
			throw new Error('pushIds is invalid');
		}else{
			for(var i=0; i<pushIds.length; i++){
				var pushId = pushIds[i] + '';
                pushId = pushId.trim();
				if(pushId.length === 0){
					throw new Error('pushIds is invalid');
				}else{
					arrPushIds.push({'push_id': pushId});
				}
			}		
		}

		//构造请求参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			push_ids: JSON.stringify(arrPushIds)
		};

		//调用API
		callAPI(API_QUERY_PUSH_STATUS, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 查询设备数
	 * @param {Function} callback(err, result) 回调函数
	 */
	this.queryDeviceNum = function(callback){

		//构造查询参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600
		};

		//调用API
		callAPI(API_QUERY_DEVICE_NUM, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 查询应用标签
	 * @param {int}      start                 开始位置
	 * @param {int}      limit                 查询数量
	 * @param {int}      validTime             配合timestamp确定请求的有效期，单位为秒，最大值为600，默认值600
	 * @param {Function} callback(err, result) 回调函数
	 */
	this.queryTags = function(start, limit, callback){

		//效验start
		if(parseInt(start) !== start || start < 0){
			start = 0;
		}

		//效验limit
		if(parseInt(limit) !== limit || limit < 1){
			limit = 100;
		}

		//构造查询参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			start: start,
			limit: limit
		};

		//调用API
		callAPI(API_QUERY_TAGS, params, "POST", 10000, this.secretKey, callback);

	};

	/**
	 * 取消尚未触发的定时推送任务
	 * @param {int}      pushId                消息推送id
	 * @param {Function} callback(err, result) 回调函数
	 */
	this.cancelTimingTask = function(pushId, callback){

		//效验pushId
        pushId += '';
        pushId = pushId.trim();
		if(pushId.length === 0){
			throw new Error('pushId is invalid');
		}

		//构造查询参数
		var params = {
			access_id: this.accessId,
			timestamp: Math.round((new Date()).getTime() / 1000),
			valid_time: 600,
			push_id: pushId
		};

		//调用API
		callAPI(API_CANCEL_TIMING_TASK, params, "POST", 10000, this.secretKey, callback);

	};

    /**
     * 批量为token设置标签
     * @param {array}    tagsTokensMap         tag和token的二维数组，每次最多设置20对。如：[['tag1', 'token1'], ['tag2', 'token2']]。
     * @param {Function} callback(err, result) 回调函数
     */
    this.setTags = function(tagsTokensMap, callback){

        var isTagsTokensMapValid = true;

        //校验tagsTokensMap
        if(!util.isArray(tagsTokensMap) || tagsTokensMap.length < 1 || tagsTokensMap.length > 20){
            isTagsTokensMapValid = false;
        }else{
            for(var i = 0; i < tagsTokensMap.length; i++){
                if(!util.isArray(tagsTokensMap[i]) || tagsTokensMap[i].length !== 2){
                    isTagsTokensMapValid = false;
                    break;
                }else{

                    tagsTokensMap[i][0] += '';
                    tagsTokensMap[i][0] = tagsTokensMap[i][0].trim();

                    tagsTokensMap[i][1] += '';
                    tagsTokensMap[i][1] = tagsTokensMap[i][1].trim();

                    if(tagsTokensMap[i][0].length === 0 || tagsTokensMap[i][1] === 0){
                        isTagsTokensMapValid = false;
                        break;
                    }

                }
            }
        }

        if(!isTagsTokensMapValid){
            throw new Error('tagsTokensMap is invalid');
        }

        //构造查询参数
        var params = {
            access_id: this.accessId,
            timestamp: Math.round((new Date()).getTime() / 1000),
            valid_time: 600,
            tag_token_list: JSON.stringify(tagsTokensMap)
        };

        //调用API
        callAPI(API_SET_TAGS, params, "POST", 10000, this.secretKey, callback);

    };

    /**
     * 批量为token删除标签
     * @param {array}    tagsTokensMap         tag和token的二维数组，每次最多设置20对。如：[['tag1', 'token1'], ['tag2', 'token2']]。
     * @param {Function} callback(err, result) 回调函数
     */
    this.deleteTags = function(tagsTokensMap, callback){

        var isTagsTokensMapValid = true;

        //校验tagsTokensMap
        if(!util.isArray(tagsTokensMap) || tagsTokensMap.length < 1 || tagsTokensMap.length > 20){
            isTagsTokensMapValid = false;
        }else{
            for(var i = 0; i < tagsTokensMap.length; i++){
                if(!util.isArray(tagsTokensMap[i]) || tagsTokensMap[i].length !== 2){
                    isTagsTokensMapValid = false;
                    break;
                }else{

                    tagsTokensMap[i][0] += '';
                    tagsTokensMap[i][0] = tagsTokensMap[i][0].trim();

                    tagsTokensMap[i][1] += '';
                    tagsTokensMap[i][1] = tagsTokensMap[i][1].trim();

                    if(tagsTokensMap[i][0].length === 0 || tagsTokensMap[i][1] === 0){
                        isTagsTokensMapValid = false;
                        break;
                    }

                }
            }
        }

        if(!isTagsTokensMapValid){
            throw new Error('tagsTokensMap is invalid');
        }

        //构造查询参数
        var params = {
            access_id: this.accessId,
            timestamp: Math.round((new Date()).getTime() / 1000),
            valid_time: 600,
            tag_token_list: JSON.stringify(tagsTokensMap)
        };

        //调用API
        callAPI(API_DELETE_TAGS, params, "POST", 10000, this.secretKey, callback);

    };

    /**
     * 根据设备token查询标签
     * @param {string}   deviceToken 设备token
     * @param {function} callback    回调函数
     */
    this.queryTagsByDeviceToken = function(deviceToken, callback){

        //校验token
        deviceToken += '';
        deviceToken = deviceToken.trim();

        if(deviceToken.length === 0){
            throw new Error('deviceToken is invalid');
        }

        //构造查询参数
        var params = {
            access_id: this.accessId,
            timestamp: Math.round((new Date()).getTime() / 1000),
            valid_time: 600,
            device_token: deviceToken
        };

        //调用API
        callAPI(API_QUERY_TAGS_BY_DEVICE_TOKEN, params, "POST", 10000, this.secretKey, callback);
    };

    /**
     * 根据标签查询设备数
     * @param {string}   tag      标签
     * @param {function} callback 回调函数
     */
    this.queryDeviceNumByTag = function(tag, callback){

        //校验tag
        tag += '';
        tag = tag.trim();

        if(tag.length === 0){
            throw new Error('tag is invalid');
        }

        //构造查询参数
        var params = {
            access_id: this.accessId,
            timestamp: Math.round((new Date()).getTime() / 1000),
            valid_time: 600,
            tag: tag
        };

        //调用API
        callAPI(API_QUERY_DEVICE_NUM_BY_TAG, params, "POST", 10000, this.secretKey, callback);
    };


}
1135499
public OpenUser userInfo(String accessToken, String openId, String lang) {
        String url = WxEndpoint.get("url.oauth.userinfo.get");
        String formatUrl = String.format(url, accessToken, openId, lang);

        logger.debug("get user info {}", formatUrl);
        String response = wxClient.get(formatUrl, false);
        return JsonMapper.defaultMapper().fromJson(response, OpenUser.class);
    }
121927
public static QueryrecoresultfortextResult queryrecoresultfortext(String accessToken, String voiceId, String lang) {
        HttpUriRequest httpUriRequest = RequestBuilder.post()
                .setUri(BASE_URI + "/cgi-bin/media/voice/queryrecoresultfortext")
                .addParameter(PARAM_ACCESS_TOKEN, API.accessToken(accessToken))
                .addParameter("voice_id", voiceId)
                .addParameter("lang", lang == null || lang.isEmpty() ? "zh_CN" : lang)
                .build();

        return LocalHttpClient.executeJsonResult(httpUriRequest,
                QueryrecoresultfortextResult.class);
    }
237347
public function getUser( $snsUser, $accessToken ) {

		$snsProfile = $this->getByTypeSnsId( SnsConnectGlobal::SNS_TYPE_TWITTER, $snsUser->id );

		$user = null;

		if( isset( $snsProfile ) ) {

			// TODO: Check the update method
			//$snsProfile = $this->update( $snsProfile, [ 'snsUser' => $snsUser, 'accessToken' => $accessToken ] );

			$user = $snsProfile->user;

			return $user;
		}
		else if( isset( $snsUser->email ) ) {

			$user = $this->userService->getByEmail( $snsUser->email );

			if( !isset( $user ) ) {

				// Create User
				$user = $this->register( $snsUser );

				// Add User to current Site
				$this->siteMemberService->create( $user );

				// Trigger Mail
				Yii::$app->snsLoginMailer->sendRegisterTwitterMail( $user );
			}

			$snsProfile	= $this->create( $user, [ 'snsUser' => $snsUser, 'accessToken' => $accessToken ] );

			return $user;
		}

		return false;
	}
801947
public static UserTagGetResult userTagGet(String access_token,Integer tagid,String next_openid){
		String json = String.format("{\"tagid\":%d,\"next_openid\":\"%s\"}",tagid,next_openid==null?"":next_openid);
		HttpUriRequest httpUriRequest = RequestBuilder.post()
										.setHeader(jsonHeader)
										.setUri(BASE_URI+"/cgi-bin/user/tag/get")
										.addParameter(PARAM_ACCESS_TOKEN, API.accessToken(access_token))
										.setEntity(new StringEntity(json,Charset.forName("utf-8")))
										.build();
		return LocalHttpClient.executeJsonResult(httpUriRequest,UserTagGetResult.class);
	}
912924
public List<User> batchGet(String... openIds) {
        if(openIds.length > 100) {
            throw new WxRuntimeException(999, "批量获取用户基本信息。最多支持一次拉取100条");
        }
        List<Map<String, String>> list = new ArrayList<>();
        for (String openId: openIds) {
            Map<String, String> map = new HashMap<>();
            map.put("openid", openId);
            map.put("lang", "zh_CN");
            list.add(map);
        }
        return batchGet(list);
    }
62683
public boolean validToken(String token, String openid) {
        BeanUtil.requireNonNull(token, "token is null");
        BeanUtil.requireNonNull(openid, "openid is null");
        String url = BASE_API_URL + "sns/auth?access_token=" + token + "&openid=" + openid;
        BaseResponse r = executeGet(url);
        return isSuccess(r.getErrcode());
    }