springboot+h5页面+微信公众号获取微信用户信息

article/2025/10/1 18:39:44

springboot项目,h5页面通过微信公众号获取微信用户信息
最近本人有一个项目需求,微信公众号里点击一个菜单进入一个商城购物系统。
对于在微信公众号还是小白的我来说难度有点大,但是做完后发现也就这样,用多了就熟悉了。下面记录一下自己开发过程中遇到的一些问题以及解决方案。有好多也是自己在网上找的资料,自己慢慢整合起来的。所以你可能会看到好多差不多的代码。
准备工作:
首先搭建springboot+shiro权限管理框架,在此基础上开发微信H5页面以及商城的后台管理系统。使用MySQL数据库。开发工具idea。
在github上找了一个springboot+shiro后台管理项目。本人觉得简洁,实用,附上链接
https://blog.csdn.net/zwzw1219/article/details/81813201
项目框架好了,然后H5页面在网上找了一个简单的商城模板。该H5模板也是自己在CSDN上面花积分下载下来的。该模板还是有些小问题的,需要自己去修改。
模板链接: https://pan.baidu.com/s/1k-bjTtbW9lDB66bP1ESWmA 提取码: bvrr 复制这段内容后打开百度网盘手机App,操作更方便哦
HBuilderX工具链接: https://pan.baidu.com/s/1F6XYM1Z4u2NMaa7QHqCPKQ 提取码: wime 复制这段内容后打开百度网盘手机App,操作更方便哦
项目框架有了,前端页面也有了,接下来准备微信公众号(自己申请一个微信测试公众号,然后在里面给自己开发者权限,这样才能再微信web开发者工具本地调试)
附上操作流程:
1.自己准备一个带域名的服务器资源。因为微信公众号需要域名。
我自己没有去弄域名了,而且麻烦不方便本地开发,所以在网上找了一个内网穿刺工具,每天有8个小时的免费使用时间。如果当中不能使用域名后,关掉重启,重新敲命令,获取域名。同时微信公众平台接口测试账号里面也要修改域名。
附上链接: https://pan.baidu.com/s/1i1zZwC1IJe3NQXlEmIUc1w 提取码: php6 复制这段内容后打开百度网盘手机App,操作更方便哦
2.进入微信公众平台接口测试帐号申请
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
在这里插入图片描述
直接点击登录,手机微信端确认
在这里插入图片描述
登录后,拿到APPID和appsecret 去微信公众平台调试工具获取token
http://mp.weixin.qq.com/debug/cgi-bin/apiinfo
在这里插入图片描述
接着到微信公众平台测试号管理,也就刚刚的第一个微信链接
在这里插入图片描述
这个接口配置信息 URL为项目微信用户授权页面(域名+项目文件)
token为上面的token。(我的一直配置失败,但是后面发现没有影响到本地开发)
在这里插入图片描述
点击修改,可以修改域名
此域名为 内网穿刺工具生成的域名 敲命令 ngrok http 本地项目端口号
在这里插入图片描述
在这里插入图片描述
扫码,添加微信测试公众号。
然后 体验接口权限表–网页服务–网页帐号–网页授权获取用户基本信息–修改
在这里插入图片描述
此域名和之前的那个一样。

准备了这么多后,开始代码了

微信授权接口js,该js我放在了访问进来的首页.html

$(document).ready(function() {center.enterWxAuthor();
})
// 自己的那个微信appid
var WX_APPID = "wx8eXXXXXXX68aa";
// 此路径需和微信接口配置一样
var pageUrl = pathUrl + "pages/shop/shop_index.html";
var center = {init: function(){// 渲染首页console.log("渲染首页");},enterWxAuthor: function(){debuggervar wxUserInfo = localStorage.getItem("wxUserInfo");if (!wxUserInfo) {var code = getUrlParam('code');if (code) {getWxUserInfo(code);center.init();}else{//没有微信用户信息,没有授权-->> 需要授权,跳转授权页面var authorizeUrl ='https://open.weixin.qq.com/connect/oauth2/authorize?appid='+ WX_APPID+'&redirect_uri='+ pageUrl+'&response_type=code&scope=snsapi_userinfo#wechat_redirect';window.location.href =authorizeUrl;}}else{center.init();}}
}function getWxUserInfo(par){var code = getUrlParam("code");if (par) code = par;var authorizationUrl = pathUrl + "shopApi/authorization";$.get(authorizationUrl,{code:code},function (data) {//保证写入的wxUserInfo是正确的if(data.status == 200){localStorage.setItem("wechatUserid",data.data.id);localStorage.setItem('wxUserInfo',JSON.stringify(data.data));//写缓存--微信用户信息}},"json");}

common.js 自己取舍相关代码

//form序列化为json
$.fn.serializeObject = function()
{var o = {};var a = this.serializeArray();$.each(a, function() {if (o[this.name] !== undefined) {if (!o[this.name].push) {o[this.name] = [o[this.name]];}o[this.name].push(this.value || '');} else {o[this.name] = this.value || '';}});return o;
};//获取url后的参数值
function getUrlParam(key) {var href = window.location.href;var url = href.split("?");if(url.length <= 1){return "";}var params = url[1].split("&");for(var i=0; i<params.length; i++){var param = params[i].split("=");if(key == param[0]){return param[1];}}
}// Get Root Dir
getRootDir = function (js) {var path = "";var strFullPath = window.document.location.href;var strPath = window.document.location.pathname;var pos = strFullPath.indexOf(strPath);var prePath = strFullPath.substring(0, pos);var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1);var path = prePath + postPath + "/";return path;
}getRootDirURL = function (js) {var path = "";var strFullPath = window.document.location.href;var strPath = window.document.location.pathname;var pos = strFullPath.indexOf(strPath);var prePath = strFullPath.substring(0, pos);var path = prePath + "/";return path;
}// 项目根目录
var projectPath = getRootDir("common.js");
var pathUrl = getRootDirURL("common.js");
var imagePath = getRootDir("common.js");
// 手机号
var mobileReg = /^1[3|4|5|7|8]\d{9}$/;
// 邮箱
var emailReg = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/;
// 邮编
var zipcodeReg = /[1-9]\d{5}(?!\d)/;
// 正整数
var regPositive = /^[1-9]\d*$/;
//整数
var regInteger = /^[0-9]*$/;
// IP地址
var ipReg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
// 身份证号码为15位或者18位,15位时全为数字,18位前17位为数字,最后一位是校验位,可能为数字或字符X
var iDReg = /^([0-9]{17}[0-9X]{1})|([0-9]{15})$/;
// 英文
var englishReg = /[a-zA-Z]/;
// 中文
var cnReg = /[\u4e00-\u9fa5]/;
// 正数金额
var regAmount = /(^[1-9](\d+)?(\.\d{1,2})?$)|(^0$)|(^\d\.\d{1,2}$)/ ;(function ($) {$.extend({// 替换全部replaceAll: function (str, str1, str2) {return str.replace(new RegExp(str1, "gm"), str2);},// 为空检查checkNull: function (obj) {return !$.trim(obj);},// 手机号检查checkMobile: function (obj) {return !(mobileReg.test(obj));},// 邮箱检查checkEmail: function (obj) {return !(emailReg.test(obj));},// 邮编检查checkZipcode: function (obj) {return !(zipcodeReg.test(obj));},// 正整数检查checkPositive: function (obj) {return !(regPositive.test(obj));},// IP地址检查checkIp: function (obj) {return !(ipReg.test(obj));},// 身份证检查checkID: function (obj) {return !(iDReg.test(obj));},// 英文检查checkEn: function (obj) {return !(englishReg.test(obj));},// 中文检查checkEn: function (obj) {return !(cnReg.test(obj));},// 正整数金额checkAmount: function (obj) {return !(regAmount.test(obj));}});
})(jQuery);// 日期比较yyyy-MM-dd
function dateCompare(startDate, endDate) {if (startDate == '' || endDate == '') {return;}var arr = startDate.split("-");var starttime = new Date(arr[0], arr[1], arr[2]);var starttimes = starttime.getTime();var arrs = endDate.split("-");var lktime = new Date(arrs[0], arrs[1], arrs[2]);var lktimes = lktime.getTime();if (starttimes >= lktimes) {return true;} else {return false;}
}function checkNull(val) {if (val == null || $.trim(val).length == 0) {return true;}return false;
}//手机号检查
function checkMobile(obj) {return !(mobileReg.test(obj));
}// 邮箱检查
function checkEmail(obj) {return !(emailReg.test(obj));
}// 邮编检查
var zipReg = /^[1-9][0-9]{5}$/;function checkZipcode(obj) {return !(zipReg.test(obj));
}// 正整数检查
function checkPositive(obj) {return !(regPositive.test(obj));
}// 整数检查
function checkInteger(obj) {return !(regInteger.test(obj));
}// IP地址检查
function checkIp(obj) {return !(ipReg.test(obj));
}// 身份证检查
function checkID(obj) {return !(iDReg.test(obj));
}// 英文检查
function checkEn(obj) {return !(englishReg.test(obj));
}// 中文检查
function checkCh(obj) {return !(cnReg.test(obj));
}// 正整数金额
function checkAmount(obj) {return !(regAmount.test(obj));
}// 小数检查
var pointReg = /^\d+\.\d+$/;function checkPoint(obj) {return !(pointReg.test(obj));
}//验证年月日(yyyy-mm-dd)格式
function isDate(dateString) {var r = dateString.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2})$/);if (r == null) {return false;}var d = new Date(r[1], r[3] - 1, r[4]);var num = (d.getFullYear() == r[1] && (d.getMonth() + 1) == r[3] && d.getDate() == r[4]);return (num != 0);
}

ShopApiController

    /*** @Author zhangfeng* @Description //TODO 首页 获取微信用户信息* @Date 2019/5/23 14:00* @Param [code, request, response]* @return com.otfresh.utils.ServerResponse**/@GetMapping("/authorization")@ResponseBodypublic ServerResponse authorizationWeixin( @RequestParam String code,HttpServletRequest request,HttpServletResponse response) throws IOException {request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");try {return  iWechatUserService.getOauthAccessToken(code);} catch (Exception e) {logger.error("RestFul of authorization is error.",e);}return ServerResponse.createByError();}

ServerResponse.java 为返回工具类,需要的朋友可以自己保存

package com.otfresh.utils;import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;import java.util.Date;;/*** * { data: status/code: msg:* * }* * 统一返回值* * @author Administrator* @param*///将该标记放在属性上,如果该属性为NULL则不参与序列化 
//如果放在类上边,那对这个类的全部属性起作用 
//Include.Include.ALWAYS 默认 
//Include.NON_DEFAULT 属性为默认值不序列化 
//Include.NON_EMPTY 属性为 空(“”) 或者为 NULL 都不序列化 
//Include.NON_NULL 属性为NULL 不序列化 
@JsonInclude(Include.NON_NULL)
public class ServerResponse {private int status;private String msg;private String field;private Object data;// 私有构造函数private ServerResponse(int status) {this.status = status;}// 私有构造函数private ServerResponse(int status, Object data) {this.status = status;this.data = data;}// 私有构造函数private ServerResponse(int status, String msg, Object data) {this.status = status;this.msg = msg;this.data = data;}// 私有构造函数private ServerResponse(int status, String msg) {this.status = status;this.msg = msg;}// 验证私有构造函数private ServerResponse(int status, String field, String msg, Object data) {this.status = status;this.field = field;this.msg = msg;this.data = data;}// 使之不在json序列化结果当中@JsonIgnorepublic boolean isSuccess() {return this.status == ResponseCode.SUCCESS.getCode();}@JsonFormat(pattern = "yyyy/MM/dd HH:mm:ss")public Date getDate() {return new Date();}public int getStatus() {return status;}public Object getData() {return data;}public String getMsg() {return msg;}public String getField() {return field;}// 正确返回public static ServerResponse createBySuccess() {return new ServerResponse(ResponseCode.SUCCESS.getCode());}public static ServerResponse createBySuccessMessage(String msg) {return new ServerResponse(ResponseCode.SUCCESS.getCode(), msg);}public static ServerResponse createBySuccess(Object data) {return new ServerResponse(ResponseCode.SUCCESS.getCode(), data);}public static ServerResponse createBySuccess(String msg, Object data) {return new ServerResponse(ResponseCode.SUCCESS.getCode(), msg, data);}public static ServerResponse createBySuccess(ResponseCode responseCode) {return new ServerResponse(responseCode.getCode(), responseCode.getDesc());}public static ServerResponse createBySuccess(ResponseCode responseCode, Object data) {return new ServerResponse(responseCode.getCode(), responseCode.getDesc(), data);}// error返回public static ServerResponse createByError() {return new ServerResponse(500, ResponseCode.ERROR.getDesc());}public static ServerResponse createByErrorMessage(String errorMessage) {return new ServerResponse(ResponseCode.ERROR.getCode(), errorMessage);}public static ServerResponse createByErrorCodeMessage(int errorCode, String errorMessage) {return new ServerResponse(errorCode, errorMessage);}public static ServerResponse createByErrorCodeMessage(ResponseCode responseCode) {return new ServerResponse(responseCode.getCode(), responseCode.getDesc());}public static ServerResponse createByErrorValidator(int code,String field,String message) {return new ServerResponse(code, field,message,null);}public static ServerResponse createByErrorValidator(int code,String field,String message,Object data) {return new ServerResponse(code, field,message,data);}}

ResponseCode.java

package com.otfresh.utils;/*** Created by geely enum类*/
public enum ResponseCode {SUCCESS(200, "SUCCESS"), ERROR(400, "ERROR"), NEED_LOGIN(100, "NEED_LOGIN"), ERROR_LOGIN(401, "你输入的账号和密码有误!!"),ERROR_CODE_LOGIN(402, "你输入的验证有误!!"), SESSION_FAIIL(101, "SESSION IS CLOSED"), ILLEGAL_ARGUMENT(202, "ILLEGAL_ARGUMENT");private final int code;private final String desc;ResponseCode(int code, String desc) {this.code = code;this.desc = desc;}public int getCode() {return code;}public String getDesc() {return desc;}}

IWechatUserService.java

/*** 根据code 获取授权的token 仅限授权时使用,与全局的access_token不同* @param code* @return String 用户信息* @throws IOException* @throws ClientProtocolException*/ServerResponse getOauthAccessToken(String code) throws Exception;

WechatUserServiceImpl.java

package com.otfresh.service.impl;import com.alibaba.fastjson.JSONObject;
import com.otfresh.dao.WechatUserDao;
import com.otfresh.model.dto.WechatUserDTO;
import com.otfresh.model.po.AccessTokenDO;
import com.otfresh.model.vo.WechatUserVO;
import com.otfresh.service.IAccessTokenService;
import com.otfresh.service.IWechatUserService;
import com.otfresh.utils.ServerResponse;
import com.otfresh.utils.StringUtil;
import com.otfresh.utils.constants.StatusEnum;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.TrustStrategy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;import javax.net.ssl.SSLContext;
import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.*;/*** 微信用户模块 Service 实现层* @author zhangfeng* @create 2019年05月22日 09:56:34**/
@Service
public class WechatUserServiceImpl implements IWechatUserService  {protected final Logger logger = LoggerFactory.getLogger(this.getClass());@Value("${app.WX_APPID}")private String WX_APPID;@Value("${app.WX_APPSECRET}")private String WX_APPSECRET;@Value("${app.WX_OAUTH_ACCESS_TOKEN_URL}")private String WX_OAUTH_ACCESS_TOKEN_URL ;@Value("${app.WX_OAUTH_REFRESH_TOKEN_URL}")private String WX_OAUTH_REFRESH_TOKEN_URL ;@Value("${app.WX_USERINFO_URL}")private String WX_USERINFO_URL ;@Autowiredprivate WechatUserDao wechatUserDao;@Autowiredprivate IAccessTokenService accessTokenService;/*** @Author zhangfeng* @Description //TODO 更新微信用户信息* @Date 2019/5/23 9:27* @Param [wechatUserDTO]* @return WechatUserDTO**/@Transactional(rollbackFor = Exception.class)public WechatUserDTO saveOrUpdateWechatUseer(String user){JSONObject userJson = JSONObject.parseObject(user);String openid = userJson.getString("openid");String nickname = userJson.getString("nickname");String sex = userJson.getString("sex");String headimgurl = userJson.getString("headimgurl");WechatUserDTO wechatUserDTO = new WechatUserDTO();wechatUserDTO.setOpenid(openid);wechatUserDTO.setWechatName(nickname);wechatUserDTO.setHeadImg(headimgurl);if(userJson.containsKey("unionid")){String unionid = userJson.getString("unionid");wechatUserDTO.setWechatNo(unionid);}// 查询是否存在该用户WechatUserVO wechatUserByOpenId = wechatUserDao.getWechatUserByOpenId(wechatUserDTO);if(StringUtil.isNotBlank(wechatUserByOpenId)){wechatUserDTO.setId(wechatUserByOpenId.getId());wechatUserDTO.setUpdateTime(new Date());wechatUserDTO.setLastLoginTime(new Date());// 更新信息wechatUserDao.updateWechatUser(wechatUserDTO);}else{wechatUserDTO.setStatus(StatusEnum.NEW.getKey().toString());wechatUserDTO.setSex(sex);// 新增信息wechatUserDao.saveWechatUser(wechatUserDTO);}return wechatUserDTO;}/*** 根据code 获取授权的token 仅限授权时使用,与全局的access_token不同* @param code* @return* @throws IOException* @throws ClientProtocolException*/@Override@Transactional(rollbackFor = Exception.class)public ServerResponse getOauthAccessToken(String code) throws Exception {// 从数据库表查询token信息AccessTokenDO accessToken = accessTokenService.getAccessTokenById(1);String rs_access_token = null;String rs_openid = null;//通过code换取网页授权access_tokenString url = WX_OAUTH_ACCESS_TOKEN_URL + "?appid="+WX_APPID+"&secret="+WX_APPSECRET+"&code="+code+"&grant_type=authorization_code";// 如果token为null 或者 超过过期时间if(accessToken == null || accessToken.getCreateTime().getTime() + Long.parseLong(accessToken.getExpiresIn()) *1000 < System.currentTimeMillis()){synchronized (this) {//已过期,需要刷新String rh = restTemplate().getForObject(url, String.class);JSONObject json = JSONObject.parseObject(rh);if(json.containsKey("errcode")){return ServerResponse.createByErrorCodeMessage(Integer.parseInt(json.get("errcode").toString()),json.get("errmsg").toString());}// 如果token为null 则不刷新tokenif(accessToken == null ){String access_token = json.getString("access_token");String expires_in = json.getString("expires_in");rs_openid = json.getString("openid");rs_access_token = access_token;accessToken = new AccessTokenDO();accessToken.setId(1);accessToken.setAccessToken(access_token);accessToken.setExpiresIn(expires_in);accessTokenService.saveAccessToken(accessToken);}else{String refresh_token = json.getString("refresh_token");// 刷新access_tokenString refresh_url = WX_OAUTH_REFRESH_TOKEN_URL+"?appid="+WX_APPID+"&grant_type=refresh_token&refresh_token="+refresh_token;String r_rh = restTemplate().getForObject(refresh_url, String.class);JSONObject r_json = JSONObject.parseObject(r_rh);if(r_json.containsKey("errcode")){return ServerResponse.createByErrorCodeMessage(Integer.parseInt(r_json.get("errcode").toString()),r_json.get("errmsg").toString());}String r_access_token = r_json.getString("access_token");String r_expires_in = r_json.getString("expires_in");rs_openid = r_json.getString("openid");rs_access_token = r_access_token;accessToken = new AccessTokenDO();accessToken.setId(1);accessToken.setAccessToken(r_access_token);accessToken.setExpiresIn(r_expires_in);accessTokenService.updateAccessToken(accessToken);}}}else{//还没有过期String rh = restTemplate().getForObject(url, String.class);JSONObject json = JSONObject.parseObject(rh);if(json.containsKey("errcode")){return ServerResponse.createByErrorCodeMessage(Integer.parseInt(json.get("errcode").toString()),json.get("errmsg").toString());}rs_access_token = json.getString("access_token");rs_openid = json.getString("openid");}return getOauthUserInfo(rs_access_token,rs_openid);}/*** 根据授权token获取用户信息* @param access_token* @param openid* @return*/@Transactional(rollbackFor = Exception.class)public ServerResponse getOauthUserInfo(String access_token,String openid)  {String url = WX_USERINFO_URL +"?access_token="+ access_token +"&openid="+ openid +"&lang=zh_CN";try {String user = restTemplate().getForObject(url, String.class);user = new String(user.getBytes("ISO-8859-1"), "UTF-8");JSONObject userJson = JSONObject.parseObject(user);if(userJson.containsKey("errcode")){return ServerResponse.createByErrorCodeMessage(Integer.parseInt(userJson.get("errcode").toString()),userJson.get("errmsg").toString());}//保存用户信息WechatUserDTO wechatUserDTO = this.saveOrUpdateWechatUseer(user);return ServerResponse.createBySuccess(wechatUserDTO);} catch (Exception e) {logger.error("RestFul of authorization is error.",e);}return ServerResponse.createByError();}// 使用spring的RestTemplate 进行https请求 ,不懂的可以在网上搜索RestTemplate public static RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();HttpComponentsClientHttpRequestFactory requestFactory =new HttpComponentsClientHttpRequestFactory();requestFactory.setHttpClient(httpClient);RestTemplate restTemplate = new RestTemplate(requestFactory);return restTemplate;}
}

IAccessTokenService 为保存accessToken 而设计的。本人用的spring 的 ehcache缓存技术+数据表保存accessToken ,当然此处也可以使用redis。网上也有这种方案,本文不再记录。附上本人参考的链接https://blog.csdn.net/jiepan9178/article/details/81449004
注解形式获取参数,注意发布到测试环境或者真实环境微信APPID和appsecret需要根据自己的实际情况填写
application.properties

# 微信appId 和appsecret
app.WX_APPID=wxc524XXXXXXXXX0b8
app.WX_APPSECRET=901XXXXXXXXXXXXXXXXe2e00
#通过code换取网页授权access_token Url
app.WX_OAUTH_ACCESS_TOKEN_URL=https://api.weixin.qq.com/sns/oauth2/access_token
#刷新access_token url
app.WX_OAUTH_REFRESH_TOKEN_URL=https://api.weixin.qq.com/sns/oauth2/refresh_token
#获取微信用户 url
app.WX_USERINFO_URL = https://api.weixin.qq.com/sns/userinfo

其中的实体相关类和service类,dao层,mapper,SQL就不贴代码了无非就是CRUD,主要核心代码是getOauthAccessToken这个方法。

好了,代码都准备了好了,那开始来测试了
测试工具为 微信web开发者工具,账号就是之前设置开发者权限的微信账号登录。选择公众号网页调试。地址栏输入 之前在微信公众平台测试号 里面设置的回调域名 + 项目的访问页面。然后就可以调试了。
以上自己测的没有问题,但是难保在诸位博友的项目中会出现各种问题,遇到问题不要急,一步一步慢慢解决。本人在编写这部分代码时,因为不懂,出现过各种问题,比如微信开发者工具无法正常访问本地网页,无法获取微信用户信息等等。最后都一步一步慢慢解决了。该代码块目前只在本地开发过,还没有发布到测试环境使用,估计还会有坑!!!!!!
好了,本地开发获取微信用户信息的相关代码就到这里了,本人小白一个,代码有不正确的地方还请各位博友指出。


http://chatgpt.dhexx.cn/article/akdWC56P.shtml

相关文章

【公众号】微信进入公众号链接自动获取授权登陆

文章目录 前言一、准备二、开发2.1 搭建项目2.2 WeixinUtil 工具2.3 回调接口与登陆接口2.4 过滤器自动登陆2.4 其他类2.5 测试 三、总结 前言 最近项目上有一个需求&#xff0c;用户反映每次从微信打开链接都需要手动登陆&#xff0c;比较繁琐&#xff0c;想点开微信连接后自…

java向微信公众号---发送模板和图文消息

微信公众号初次开发 其他操作 项目搭建mavenapplication.ymlyml参数配置微信客户端配置 搭建完成 实现业务模板消息推送准备工作模板消息填写要求图文消息填写要求 推送模板消息推送模板消息结果——效果 推送图文消息推送图文消息工具类问题和结果 获取关注的用户openId既然有…

微信公众号接入天行机器人案例和方法

首先使用的是天行机器人&#xff1a; 1、接入基本原理&#xff1a; https://www.tianapi.com/apiview/47 申请完成后的结果如下 调用对应的接口的参数如下&#xff1a; http://api.tianapi.com/txapi/robot/index?keyae5e9a72c8d4cb1f5e096f7bb4daf1f3&questionrobot…

微信公众号的端口映射及服务开发

一. 开发准备 微信公众号申请---->实名认证---->服务器开发---->绑定服务器 PS: 这里有一点需要注意的就是, 微信开发必须是80端口或者443端口, 如果我们有云服务器主机一切都好办. 但是如果没有我们还有几个备选方案: 1. 花生壳 , net123 : 这两个都需要实名认证(…

[JAVA实现]微信公众号网页授权登录,java开发面试笔试题

我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家。 扫描二维码或搜索下图红色VX号,加VX好友,拉你进【程序员面试学习交流群】免费领取。也欢迎各位一起在群里探讨技术。 推荐文章:Java 面试知识点解析;Mysql优化技巧…

后端操作微信公众号

一、功能说明 员工端使用微信公众号完成审批操作&#xff0c;涉及到的功能包含&#xff1a;自定义菜单、授权登录、消息 1、微信公众号一级菜单为&#xff1a;审批列表、审批中心、我的 2、员工关注公众号&#xff0c;员工第一次登录微信公众号&#xff0c;通过微信授权登录进行…

Java基于微信公众号接口实现授权登录源码及原理分析

微信公众号授权登录操作前提必须注册微信公众平台账号&#xff0c;注意的是订阅号不支持授权登录操作&#xff0c;因此对于个人开发者注册的订阅号是无法实现的&#xff0c;必须注册企业号的微信平台账号而具体注册流程就不详细介绍了&#xff0c;有什么疑问可去微信公众号平台…

微信公众号多域名回调系统1.0发布

这是一款基于ThinkPHP6.0框架的微信公众号多域名回调系统。 微信公众号后台默认只能授权2个网页域名&#xff0c;用本系统可突破这个限制&#xff0c;用同一个公众号对接无限多个网站。网站后台支持回调域名白名单的管理&#xff0c;以及登录记录的查看。 本系统还有微信access…

PHP微信扫码关注公众号并授权登录源码

PHP微信扫码登录看起来简单&#xff0c;但做起来有点麻烦&#xff0c;开发起来就会浪费很多的时间。 PHP判断是否首次关注公众号&#xff0c;扫码关注公众号获取微信用户头像、openid和省市等信息源码。 演示体验地址: https://www.skpan.cn/user/login.html 网盘下载地址:…

2023最新微信公众号无限回调系统源码/已修复BUG亲测可用

正文: 测试环境&#xff1a; Nginx 1.20.2 MySQL 5.6.50 PHP-7.2 1.创建站点 2.到根目录上传源码 3.创建数据库并导入 4.修改数据库信息 根目录/config.php 第5&#xff0c;6&#xff0c;7行 5.后台地址域名/admin 账号admin 密码123456 6.修改域名 根目录下 api.php 第…

Java微信公众号开发登录

MySQL基础开发篇 这部分的内容应该更合适那些刚入坑的朋友们或者是对于基础部分掌握不牢固的朋友,因此有一定经验的或者基础不错的可以自动跳至下一章内容阅读,这部分我仅把目录内容截图展示。 MySQL的优化以及管理维护 MySQL作为一款关系型数据库,SQL语句的优化是尤其重要的…

mysql 推送微信公众号_10分钟完成微信公众号第三方平台全网发布

背景&#xff1a;在微信公众平台配置服务器URL时&#xff0c;使用了新浪云SAE自带的二级域名&#xff0c;提交时出现一个安全风险的警告&#xff0c;网上查了下&#xff0c;许多服务平台和团队也遇到同样的问题。 经过一番研究 … 为什么会有安全风险的警告&#xff1f; 微信公…

springboot微信公众号管理系统vue内容文章文件上传jsp源码mysql

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当做编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 这是一个基于springbootvue的微信公众号管理系统 二…

微信公众号迁移,需要做些什么

❤️ 个人主页&#xff1a;水滴技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; &#x1f338; 订阅专栏&#xff1a;微信公众平台 文章目录 一、开通开发者二、设置IP白名单三、自定义菜单四、认证五、网页授权域名六、模板消息七、转换…

PHP微信公众号网页授权登录 扫码登录 获取用户基本信息

前言 现在微信登录是一个网站、APP的标配&#xff0c;所以微信授权登录是我们应该要掌握的。微信授权登录有4种方式&#xff1a; 1、通过微信开放平台2、通过认证的微信服务号3、通过认证的微信订阅号4、通过微信小程序曲线救国 今天我们就讲解的是微信服务号&#xff0c;通…

微信公众号多域名回调系统

介绍&#xff1a; 这是一款基于ThinkPHP6.0框架的微信公众号多域名回调系统。 微信公众号后台默认只能授权2个网页域名&#xff0c;用本系统可突破这个限制&#xff0c;用同一个公众号对接无限多个网站。网站后台支持回调域名白名单的管理&#xff0c;以及登录记录的查看。 本…

微信公众号授权获取用户信息及jwt登录

Java 微信公众号授权获取用户信息及jwt登录 &#xff01;&#xff01;&#xff01; 前言 前几篇文章小编分享过&#xff1a; 微信小程序授权获取用户手机号 jwt登录 (含源码)微信小程序支付 公众号支付 (含源码) 工作之余&#xff0c;分享下 “ 微信公众号授权 获取用户信…

手把手教程用Java实现微信公众号扫码登录功能

文章目录 前言一、环境准备二、使用步骤1. 使用微信工具包2. 创建数据表3. 登录页面代码逻辑4. 验证微信公众号登录 总结 前言 微信现今是我们必不可少的社交工具了&#xff0c;围绕微信这个生态实际上有很多东西可以做&#xff0c;我们经常会看到一些网站通过微信扫码进如公众…

[一维前缀和]leetcode303:区域和检索 - 数组不可变(easy)

题目&#xff1a; 题解&#xff1a; 一维前缀和&#xff0c;元素数组[0,j]的前缀和对应prefix[j1] 代码如下&#xff1a; class NumArray { private:vector<int> prefix; public://题解&#xff1a;一维前缀和NumArray(vector<int>& nums) {int nnums.size()…

前缀和矩阵前缀和

前缀和 前缀和是一种重要的预处理&#xff0c;能大大降低查询的时间复杂度。我们可以简单理解为“数列的前 n n n 项的和”。 例题 有 N N N 个的正整数放到数组 A A A 里&#xff0c;现在要求一个新的数组 B B B&#xff0c;新数组的第 i i i 个数 B [ i ] B[i] B[i]…