主页> 常见问题> 微信公众号开发网页授权获得OPENID的过滤器

微信公众号开发网页授权获得OPENID的过滤器

阅读: 常见问题
1.填写授权回调页面域名: 1.1获取微信公众平台测试账号 %u83B7%u53D6%u5FAE%u4FE1%u516C%u4F17%u5E73%u53F0%u6D4B%u8BD5%u8D26%u53F7
alt 获取微信公众平台测试账号 1.2对帐号进行接口配置填写 %u5BF9%u5E10%u53F7%u8FDB%u884C%u63A5%u53E3%u914D%u7F6E%u586B%u5199
alt 对帐号进行接口配置填写 1.3填写授权回调页面域名 1240
  • 注意域名填写不要加 http:// 或者 http://
    %u586B%u5199%u6388%u6743%u56DE%u8C03%u9875%u9762%u57DF%u540D
    alt 填写授权回调页面域名
2授权成功获得Openid
  • 主要是根据微信公众平台技术文档进行操作。2.1用户同意授权,获取code

    在确保微信公众账号拥有授权作用域的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_basesnsapi_userinfo),引导关注者打开如下页面:

http://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 
//若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
2.1.1封装普通url成授权url
  • 本人是采用过滤器的方式封装url引导用户访问上面授权链接:

      public class OpenidFilter implements Filter {
          private static String flag1 = "1";
          private static String flag2 = "2";
          @Override
          public void destroy() {
          }
    
          @Override
          public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
                  throws IOException, ServletException {
              //转换request 和 respond 
              HttpServletRequest request = (HttpServletRequest) req;
              HttpServletResponse response = (HttpServletResponse) resp;
              flag1 = request.getRequestURI();
              // 判断是否同一个路径封装成微信的路径再次访问
              System.out.println("是否同一个路径封装成微信的路径再次访问" + flag1.equals(flag2));
              if (!flag1.equals(flag2)) {
                  // 判断request中是否有openid
                  if (CheckUtil.isNullOrBlank((String) request.getSession().getAttribute("openid"))) {
                      flag2 = request.getRequestURI();
    
                      // 修改成微信的url
                      String url = WeixinUtil.AUTHORIZE_URL.replace("APPID", WeixinUtil.APPID)
          .replace("SCOPE", WeixinUtil.SCOPR)
          .replace("REDIRECT_URI", WeixinUtil.DOMAIN_NAME + request.getRequestURI());
                      System.out.println("过滤修改后的url:" + url);
                      //重定向url
                      response.sendRedirect(url);
                      return;
                  }
              }
              chain.doFilter(request, response);
          }
    
          @Override
          public void init(FilterConfig arg0) throws ServletException {
    
          }
      }
  • 此过滤器应该为一级调用,web.xml配置:

     
         openidFilter
         com.weixin.oauth.filter.OpenidFilter
     
     
         openidFilter
         /*
         1
     
  • 直接在微信Web开发工具输入需要封装的url:

    %u4F7F%u7528%u5FAE%u4FE1%u5F00%u53D1%u5DE5%u5177%u8F93%u5165url
    alt 使用微信开发工具输入url
  • 过滤修改后的url:

     http://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9240e5de6afdd7b1&redirect_uri=http://zhixiaoyi.nat300.top/weixinOAuth/OAuthServlet.do&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
2.1.2授权访问获得code
  • 之后会进入授权页面:
%u7528%u6237%u8FDB%u884C%u6388%u6743
alt 用户进行授权 2.2通过code获得openid
  • 在获得code之后需立即采用WeixinUtil通过code换取网页授权access_token。

这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openidsnsapi_base式的网页授权流程即到此为止。

  • 获得access_token的请求连接: http://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

  • 其返回JSON数据包如下:

    { "access_token":"ACCESS_TOKEN",    
      "expires_in":7200,    
      "refresh_token":"REFRESH_TOKEN",    
      "openid":"OPENID",    
      "scope":"SCOPE" }
  • 获得code和openid的servlet:

     @WebServlet(name = "OAuthServlet.do", urlPatterns = { "/OAuthServlet.do" })
     public class OAuthServlet extends HttpServlet {
    
         private static final long serialVersionUID = 1L;
    
         public OAuthServlet() {
         }
    
         protected void doGet(HttpServletRequest request, HttpServletResponse response)
                 throws ServletException, IOException {
             doPost(request, response);
         }
    
         protected void doPost(HttpServletRequest request, HttpServletResponse response)
                 throws ServletException, IOException {
             // 得到code
             String code = request.getParameter("code");
             //先检测是否已经得到openid
             String openid = (String) request.getSession().getAttribute("openid");
             if(CheckUtil.isNullOrBlank(openid)){
                 //判断cede是否为空即是否需要访问获得openid
                 if (!CheckUtil.isNullOrBlank(code)) {
                     System.out.println("code:" + code);
                     //采用WeixinUtil通过code换取网页授权access_token
                     OAuthInfo oauthInfo = WeixinUtil.getAccessToken(WeixinUtil.APPID, WeixinUtil.APPSECRET, code);
                     request.getSession().setAttribute("openid", oauthInfo.getOpenId());
                 }
             }
             request.getRequestDispatcher("index.jsp").forward(request, response);
             System.out.println("openid:" + openid);
         }
    
     }
  • WeixinUtil代码如下:

    public class WeixinUtil {
        // 公众号id
        public static String APPID = "wx9240e5de6afdd7b1";
        // 公众号密钥
        public static String APPSECRET = "2de51d7fae9cb5f36d5468c15bc288fe";
        // 用户同意授权url,获取code
        public static String AUTHORIZE_URL = "http://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect";
        // 通过code换取网页授权access_token的url
        public static String ACCESS_TOKEN_BY_CODE_URL = "http://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
        // 授权域名
        public static String DOMAIN_NAME = "http://zhixiaoyi.nat300.top";
        // url范围
        public static String SCOPR = "snsapi_userinfo";

        /**
         * Get请求
         * 
         * @param url
         * @return
         */
        public static JSONObject doGetStr(String url) {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet httpGet = new HttpGet(url);
            JSONObject jsonObject = null;
            try {
                HttpResponse httpRequest = httpClient.execute(httpGet);
                HttpEntity entity = httpRequest.getEntity();

                if (entity != null) {
String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = JSONObject.fromObject(result);
                }

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return jsonObject;
        }

        /**
         * Post请求
         * 
         * @param url
         * @param outStr
         * @return
         */
        public static JSONObject doPostStr(String url, String outStr) {

            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            JSONObject jsonObject = null;
            try {
                httpPost.setEntity(new StringEntity(outStr, "UTF-8"));
                HttpResponse httpRequest = httpClient.execute(httpPost);
                HttpEntity entity = httpRequest.getEntity();

                String result = EntityUtils.toString(entity, "UTF-8");
                jsonObject = JSONObject.fromObject(result);

            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return jsonObject;
        }

        /**
         * 网页授权获取openId第2步,根据code取得openId
         * 
         * @param appid
         *            公众号的唯一标识
         * @param secret
         *            公众号的appsecret密钥
         * @param code
         *            code为换取access_token的票据
         * @return
         */
        /**
         * 
         * 通过code获取access_token
         * 
         * @return
         */
        public static OAuthInfo getAccessToken(String appid, String secret, String code) {
            OAuthInfo oAuthInfo = new OAuthInfo();
            String url = ACCESS_TOKEN_BY_CODE_URL.replace("APPID", appid).replace("SECRET", secret).replace("CODE", code);
            JSONObject jsonObject = doGetStr(url);
            if (jsonObject != null) {
                oAuthInfo.setAccessToken(jsonObject.getString("access_token"));
                oAuthInfo.setOpenId(jsonObject.getString("openid"));
                oAuthInfo.setExpiresIn(jsonObject.getInt("expires_in"));
                oAuthInfo.setRefreshToken(jsonObject.getString("refresh_token"));
                oAuthInfo.setScope(jsonObject.getString("scope"));
            }
            return oAuthInfo;
        }

    }
  • 控制台输出结果:

     是否同一个路径封装成微信的路径再次访问false
     过滤修改后的url:http://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9240e5de6afdd7b1&redirect_uri=http://zhixiaoyi.nat300.top/weixinOAuth/OAuthServlet.do&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
     是否同一个路径封装成微信的路径再次访问true
     code:051FhwC11h9UfM1y5xE11yjBC11FhwC6
     openid:ozlH6v1yu2otJOmT1BsD24d25xBU
  • 页面展示openid:

%u9875%u9762%u5C55%u793Aopenid
alt 页面展示openid
  • 用到的pojo:

      public class OAuthInfo {
    
          // 网页授权接口调用凭证
          private String accessToken;
    
          // access_token接口调用凭证超时时间
          private int expiresIn;
    
          // 用户刷新access_token
          private String refreshToken;
    
          // 用户唯一标识
          private String openId;
    
          // 用户授权的作用域
          private String scope;
    
          public String getAccessToken() {
              return accessToken;
          }
    
          public int getExpiresIn() {
              return expiresIn;
          }
    
          public String getRefreshToken() {
              return refreshToken;
          }
    
          public String getOpenId() {
              return openId;
          }
    
          public String getScope() {
              return scope;
          }
    
          public void setAccessToken(String accessToken) {
              this.accessToken = accessToken;
          }
    
          public void setExpiresIn(int expiresIn) {
              this.expiresIn = expiresIn;
          }
    
          public void setRefreshToken(String refreshToken) {
              this.refreshToken = refreshToken;
          }
    
          public void setOpenId(String openId) {
              this.openId = openId;
          }
    
          public void setScope(String scope) {
              this.scope = scope;
          }
    
          @Override
          public String toString() {
              return "OAuthInfo [accessToken=" + accessToken + ", expiresIn=" + expiresIn + ", refreshToken=" + refreshToken
                      + ", openId=" + openId + ", scope=" + scope + "]";
          }
    
      }
3.经验总结

【温馨提示】倡导尊重与保护知识产权。如发现本站文章存在版权问题,烦请提供版权疑问、身份证明、版权证明、联系方式等发邮件至55506560@qq.com ,我们将及时处理。本站文章仅作分享交流用途,作者观点不等同于本站观点。用户与作者的任何交易与本站无关,请知悉。

客服
套餐咨询,操作答疑等
在线客服