当前位置: 首页 > 工具软件 > OpenID4Java > 使用案例 >

Java实现获取公众号用户的OpenID

郤瀚
2023-12-01

OpenID是用户在某一个公众号的唯一标识,用户不同公众号的的OpenID是不一样的。在开发的时候,我们有时需要获取用户的OpenID。本文将介绍以下内容:“用户页面授权HTML代码”、“调用服务器后端接口的js代码”、“用户静默授权后端接口”、“微信服务器回调我们的服务器接口”、“获取微信服务器返回的信息”。

1、用户页面授权HTML代码。

设计一个用户点击授权的前端页面:

<div id="loginMain">
			<div id="loginInfomation" class="layui-form">
				<h2>欢迎登录博销宝管理后台</h2>
				<div class="layui-form-item">
					<label class="layui-form-label"><strong class="requiredField">*</strong>公司编号:</label>
					 <div class="layui-input-block">
				    	<input type="text" class="layui-input" name="${Staff.FIELD_NAME_companySN}" value="" lay-verify="required|checkCompanySN" placeholder="请输入公司编号" />
				    </div>
				</div>
				<div class="layui-form-item">
					<label class="layui-form-label"><strong class="requiredField">*</strong>手机号码:</label>
					<div class="layui-input-block">
						<input type="text" class="layui-input" name="${Staff.FIELD_NAME_phone}" value="" lay-verify="required|checkPhone" maxlength="11" placeholder="请输入手机号码" />
					</div>
				</div>
				<div class="layui-form-item">
					<label class="layui-form-label"><strong class="requiredField">*</strong>密码:</label>
					<div class="layui-input-block">
						<input type="password" class="layui-input" name="${Staff.FIELD_NAME_salt}" value="" lay-verify="required|checkPassword" placeholder="请输入密码" /> 
					</div>
				</div>
				<input type="hidden" value="${identify}" name="identify">
				<input type="hidden" value="${ID}"  name="ID">
				<button class="layui-btn layui-btn-lg layui-btn-normal" lay-submit lay-filter="wxLogin">登录</button>
			</div>
		</div>

2、调用服务器后端接口的js代码。

//登录系统
	form.on("submit(wxLogin)", function(data){
		var indexLoading = layer.load(1);
		var info = data.field;
		$.ajax({
			url: wxLogin_url,
			type: 'get',
			async: true,
			dataType: "json",
			data: info,
			success: function succFunction(data) {
				console.log(data);
				layer.close(indexLoading);
				if (data) {
					if (data.ERROR != "EC_NoError") {
						if (data.msg) {
							layer.msg("<span style='font-size: 0.2rem;'>" + data.msg + "</span>");
						} else {
							layer.msg("<span style='font-size: 0.2rem;'>登录失败</span>");
						}
					} else {
						switch (info.identify) {
							case "purchasingOrder":
								window.location.href = "../wx/purchasingOrderApproval.bx?ID=" + info.ID;
								break;
							case "unSalableCommodity":
								window.location.href = "../wx/unsalableCommodity.bx";
								break;
							default:
								console.log("未定义的标识符");
								break;
						}
					}
				} else {
					layer.msg("<span style='font-size: 0.2rem;'>登录失败</span>");
				}
			},
			error: function(XMLHttpRequest, textStatus, errorThrown) {
				layer.close(indexLoading);
				layer.msg(XMLHttpRequest.status + ":" + XMLHttpRequest.statusText);
			}
		});
	})

3、用户静默授权后端接口。

用户授权后,我们才能请求微信服务器获取用户信息。根据访问code的地址GET_CODE_URL,公众号账号appid和我们设置的回调接口callback_url生成url并访问微信服务器:

/** 用户请求页面(snsapi_userinfo页面授权) */
	@RequestMapping(value = "/wxLogin") // ...
	public void toGetAuthentication(HttpServletRequest request, HttpServletResponse response) throws Exception {
		if (!canCallCurrentAction(request.getSession(), BaseAction.EnumUserScope.ANYONE.getIndex())) {
			logger.debug("无权访问本Action");
			return;
		}

		logger.info("用户访问服务器!!!网页授权!!!");

		// 检查Cookie值是否存在
		// checkCookie(request, response);// ...可能在这个函数里面已经跳转,下面的代码不需要再跳转
		String backUrl = callback_url;
		String url = String.format(GET_CODE_URL, PUBLIC_ACCOUNT_APPID, URLEncoder.encode(backUrl, "UTF-8"), "snsapi_userinfo");// ...
		// 页面重定向
		response.sendRedirect(url);
	}

4、微信服务器回调我们的服务器接口。

callBack接口是我们在用户授权的时候指定的回调接口:

/** 静默授权后,微信会回调本ACTION,获取用户OpenId 参考微信官方文档:XXXXXXX */
	@RequestMapping(value = "/callBack")
	public String getOpenId(HttpServletRequest request, HttpServletResponse response, ModelMap mm) throws ClientProtocolException, IOException, ServletException {
		if (!canCallCurrentAction(request.getSession(), BaseAction.EnumUserScope.ANYONE.getIndex())) {
			logger.debug("无权访问本Action");
			return null;
		}
		……

获取微信返回的code,用code获取openid:

logger.info("callBack===接受到微信服务器发来的请求!!!");
		String code = request.getParameter(BaseWxModel.WX_CODE);// 微信会返回code值,用code获取openid

根据获取用户openID的地址GET_OPENID_URL,公众号账号PUBLIC_ACCOUNT_APPID,公众号密码PUBLIC_ACCOUNT_SECRET和code拼接请求URL:

// 1.拼接URL
		String url = String.format(GET_OPENID_URL, PUBLIC_ACCOUNT_APPID, PUBLIC_ACCOUNT_SECRET, code); // ...

向微信端发送请求,并返回JSON数据:

JSONObject jsonObject = WxUtils.getDataFromWxServer(url);

	/** 通用函数。 向微信服务器发送Get请求,返回JSON数据。 */
	public static JSONObject getDataFromWxServer(String url) {
		HttpClient httpClient = HttpClientBuilder.create().build();

		try {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = httpClient.execute(httpGet);// 接收client执行的结果
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				String result = EntityUtils.toString(entity, "UTF-8");
				return JSONObject.fromObject(result);
			} else {
				logger.error("向微信服务器发送Get请求发生错误!");
				return null;
			}
		} catch (Exception e) {
			logger.error("向微信服务器发送Get请求发生错误:" + e.getMessage());
			return null;
		}
	}

5、获取微信服务器返回的信息。

判断返回的错误码信息:

if (jsonObject.get(BaseWxModel.WX_ERRMSG) != null) {
			request.setAttribute("msg", "授权失败!!!请重新登录!");
			response.sendRedirect("/WEB-INF/wx/wx_loginFinished.jsp");
		}

获取微信端返回的openID数据:

String openid = jsonObject.getString(WxUser.field.getFIELD_NAME_openid()); // 用户唯一标识
		String token = jsonObject.getString(WxAccessToken.field.getFIELD_NAME_accessToken()); // 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
		String expires_in = request.getParameter(WxAccessToken.field.getFIELD_NAME_accessToken()); // access_token接口调用凭证超时时间,单位(秒)
		String refresh_token = request.getParameter(BaseWxModel.WX_REFRESH_TOKEN); // 用户刷新access_token
 类似资料: