微信公众号获取openid

Posted L12345

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信公众号获取openid相关的知识,希望对你有一定的参考价值。

方式一:通过网页授权的方式获取,前提是公众号已获得网页授权

公众号获得网页授权后,配置回调域名:

 

 

当用户点击某个菜单事件时,调用项目中的xxx.jsp或xxx.html文件(http://www.xxx.com/web/wx1.jsp),内容如下:

appid:公众号的:appid
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@ include file="/commViews/taglib.jsp"%>
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes" />
</head>
<script type="text/javascript">
    window.location.href = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx59f756xxxxxxx
    &redirect_uri=http%3a%2f%2fwww.xxxx.com%2fweb%2fwx2.jsp /*(http://www.xxxx.com/web/wx2.jsp)*/
    &response_type=code&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect";
</script>
<body>
</body>
</html>

 

http://www.xxxx.com/web/wx2.jsp 获取到code后调用后台接口,通过code获取openid
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<%@ include file="/commViews/taglib.jsp" %>
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport"
          content="width=device-width, initial-scale=1.0, minimum-scale=0.5, maximum-scale=2.0, user-scalable=yes"/>
    <%@ include file="/commViews/head.jsp"%>
</head>
<script type="text/javascript">
    var is_weixin = (function () {
        return navigator.userAgent.toLowerCase().indexOf(\'micromessenger\') !== -1
    })();
    var code = getUrlParam("code");
    console.log("code:" + code);
    $(function () {
        if (code != null) {

            $.ajax({
                url: "${ctx}appsite/wx/getOpenid",
                type: "get",
                dataType: \'text\',
                data: {code: code},
                success: function (openid) {
                    // alert(openid)
                },
                error: function (msg) {
                    console.log(msg);
                }
            });

        }

    });
</script>
<body>

</body>
</html>

 

后台获取openid的接口:

import com.alibaba.fastjson.JSONObject;
import com.xxx.xxx.wechat.util.HttpRequestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Controller
@RequestMapping("/xxxx/wx")
public class AppWxController {

    @Autowired
    StxcContestUserService<StxcContestUser> stxcContestUserService;

    /**
     * 1 第一步:用户同意授权,获取code
     *
     * 2 第二步:通过code换取网页授权access_token
     *
     * 3 第三步:刷新access_token(如果需要)
     *
     * 4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
     *
     * 5 附:检验授权凭证(access_token)是否有效
     *
     * code=CODE&state=STATE
     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
     */

    /**
     * 通过code换取网页授权access_token
     * @param request
     * @param response
     * @return  access_token    网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
     *          expires_in    access_token接口调用凭证超时时间,单位(秒)
     *          refresh_token    用户刷新access_token
     *          openid    用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
     *          scope    用户授权的作用域,使用逗号(,)分隔
     */
@RequestMapping(value = "/getOpenid",produces = "application/json; charset=utf-8") @ResponseBody public String getAccess_token(HttpServletRequest request, HttpServletResponse response,Map map){ String code = request.getParameter("code"); String url = "https://api.weixin.qq.com/sns/oauth2/access_token";
Map
<String,String> params = new HashMap<String, String>();
params.put("appid","wx59f75xxxxxxxxxx");  // 此处图方便直接将 appid,secret写在这里 params.put("secret","a0ff75cf900489xxxxxxxxxxx"); params.put("code",code); params.put("grant_type","authorization_code"); String result = HttpRequestUtil.getInfoByNet(url,params,"POST","https",null); JSONObject json = JSONObject.parseObject(result); String openid = json.getString("openid"); return openid; } }

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

public class HttpRequestUtil {

    //请求地址,请求参数,请求方式,请求协议,携带参数
    public static String getInfoByNet(String url, Map<String,String> params,String requestMethod,String requestProtocol,String outputStr){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(url+"?");
        String result="";
        for (Map.Entry<String,String> arg:params.entrySet()){
            stringBuffer.append(arg.getKey()+"="+arg.getValue()+"&");
        }

        stringBuffer.deleteCharAt(stringBuffer.length() - 1);
        //System.out.println(stringBuffer);
        if(requestProtocol.equals("https")){
            result = httpsRequest(stringBuffer.toString(), requestMethod, outputStr);
            //System.out.println(result);
            return result;
        }else {
            result = httpRequest(stringBuffer.toString(), requestMethod, outputStr);
            //System.out.println(result);
            return result;
        }

    }
}

 

方式二:公众号未获得网页授权

 

登录公众号后配置如下:(可参考开发文档的 “入门指南”) https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Getting_Started_Guide.html

 

 

上面填写的Url 是自己项目中的接口,填写好后提交时公众号会发送一个GET请求到接口进行token验证。

注意:验证的时候接口必须是GET请求方式,接口是POST请求token会验证失败;等token验证成功后想把接口改为post请求也可以,

刚开始没注接口用的是post请求,token验证一直失败package com.cen.appsite.KpzsContest.controllerimport com.alibaba.fastjson.JSONObject;

import com.cen.appsite.wechat.util.HttpRequestUtil;
import org.aspectj.bridge.MessageUtil;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Controller
@RequestMapping("/xxxxx/wx")
public class KpzsWxController {

    /*
     踩坑一:用post请求,token验证一直失败
    */
//@RequestMapping(value = "/checkSignature", method = RequestMethod.POST)
   @RequestMapping(value = "/checkSignature", meghod = RequestMethod.GET)

    /*
      踩坑二:请求参数用这个,验证一直不通过
    public void checkSignature(@RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("echostr") String echostr, HttpServletResponse response) {
    */ public void checkSignature(HttpServletRequest request, HttpServletResponse response) { // xml请求解析 Map
<String, String> requestMap = null; try { requestMap = parseXml(request); } catch (Exception e) { e.printStackTrace(); } // 发送方帐号(open_id),formUserName 即为想要获取的用户的openid String fromUserName = requestMap.get("FromUserName"); // 公众帐号 String toUserName = requestMap.get("ToUserName"); // 消息类型 String msgType = requestMap.get("MsgType"); String Event = requestMap.get("Event"); String EventKey = requestMap.get("EventKey");     //回复用户消息 --图文消息 String img = "<xml>\\n" + "<ToUserName><![CDATA["+fromUserName+"]]></ToUserName>\\n" + "<FromUserName><![CDATA["+toUserName+"]]></FromUserName>\\n" + "<CreateTime>"+new Date().getTime()+"</CreateTime>\\n" + "<MsgType><![CDATA[news]]></MsgType>\\n" + "<ArticleCount>1</ArticleCount>\\n" + "<Articles>\\n" + "<item>\\n" + "<Title><![CDATA[2019“倡导绿色环保生活”科普知识挑战赛]]></Title>\\n" + "<Description><![CDATA[快来参与吧!]]></Description>\\n" + "<PicUrl><![CDATA[http://www.xxxx.com/resource/images/kpzs.png]]></PicUrl>\\n" +  //图片路径 "<Url><![CDATA[http://www.xxxx.com/web/kpzs_index.jsp?openid="+fromUserName+"]]></Url>\\n" + // 当用户点击图文消息时想要跳转的链接 "</item>\\n" + "</Articles>\\n" + "</xml>\\n";      //回复用户消息 --纯文本 String text = "<xml>\\n" + " <ToUserName><![CDATA["+fromUserName+"]]></ToUserName>\\n" + " <FromUserName><![CDATA["+toUserName+"]]></FromUserName>\\n" + " <CreateTime>"+new Date().getTime()+"</CreateTime>\\n" + " <MsgType><![CDATA[text]]></MsgType>\\n" + " <Content><![CDATA[你好啊]]></Content>\\n" + " <MsgId>1234567890123456</MsgId>\\n" + "</xml>"; try { PrintWriter out = response.getWriter(); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(request.getParameter("signature"), request.getParameter("timestamp"), request.getParameter("nonce"))) {
          //用户的所有消息都必须响应,否则用户会收到 “公众号服务存在故障”提示 if(Event != null && Event.equals("CLICK")){ //用户点击(菜单)事件 out.print(img); }else{ out.print(text); } } out.close(); } catch (IOException e) { e.printStackTrace(); } } public static Map
<String, String> parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; } }
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;

public class HttpRequestUtil {

    //请求地址,请求参数,请求方式,请求协议,携带参数
    public static String getInfoByNet(String url, Map<String,String> params,String requestMethod,String requestProtocol,String outputStr){
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(url+"?");
        String result="";
        for (Map.Entry<String,String> arg:params.entrySet()){
            stringBuffer.append(arg.getKey()+"="+arg.getValue()+"&");
        }

        stringBuffer.deleteCharAt(stringBuffer.length() - 1);
        //System.out.println(stringBuffer);
        if(requestProtocol.equals("https")){
            result = httpsRequest(stringBuffer.toString(), requestMethod, outputStr);
            //System.out.println(result);
            return result;
        }else {
            result = httpRequest(stringBuffer.toString(), requestMethod, outputStr);
            //System.out.println(result);
            return result;
        }

    }
}

 

 

以上是关于微信公众号获取openid的主要内容,如果未能解决你的问题,请参考以下文章

php微信公众号支付openid问题

JAVA获取微信小程序openid和获取公众号openid,以及通过openid获取用户信息

微信公众号开发及时获取当前用户Openid及注意事项

微信网页授权-公众号支付(获取openid用户信息等)

微信公众号开发系列-获取微信OpenID

微信公众号获取粉丝openid系统