当前位置 博文首页 > 高远的博客:java微信开发API解析(七)-网页开发-微信网页授权

    高远的博客:java微信开发API解析(七)-网页开发-微信网页授权

    作者:[db:作者] 时间:2021-09-06 22:47

    java微信开发API解析(七)-网页开发-微信网页授权

    全局说明

    * 详细说明请参考前两篇文章。
    

    本文说明

    • 本文主要完成获取用户基本信息的工作,包括(昵称、头像、地址、国家等基本信息)
    • 对于snsapi_base和snsapi_userinfo我们只演示关于snsapi_userinfo。因为snsapi_userinfo更难,如果能够理解snsapi_userinfo,那么snsapi_base不在话下。
    • 对于该部分(微信网页开发)我们只介绍如何获取用户基本信息,对于开发样式库,js-SDK、开发者工具不能再讲解。(我是搞技术的,不会UI=_+)
    • 文章最后有演示的地址和操作源码

    效果图

    图片一
    图片二,效果图

    文档原文-网页授权获取用户基本信息(摘要)

    • 文档地址:http://mp.weixin.qq.com/wiki/4/9ac2e7b1f1d22e9e57260f6553822520.html
    • 接入微信公众平台开发,开发者需要按照如下步骤完成:

      1 第一步:用户同意授权,获取code
      2 第二步:通过code换取网页授权access_token
      3 第三步:刷新access_token(如果需要)
      4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
      
    • 关于网页授权回调域名的说明

      1、在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的开发者中心页配置授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;
      2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权
      3、如果公众号登录授权给了第三方开发者来进行管理,则不必做任何设置,由第三方代替公众号实现网页授权即可
      
    • 关于网页授权的两种scope的区别说明

      1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)
      2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。
      3、用户管理类接口中的“获取用户基本信息接口”,是在用户和公众号产生消息交互或关注后事件推送后,才能根据用户OpenID来获取用户基本信息。这个接口,包括其他微信接口,都是需要该用户(即openid)关注了公众号后,才能调用成功的。    
      
    • 理解

      • 在开发之前我们需要填写回调地址,该地址就是我们项目的服务器地址(ip或者域名)
      • 我们需要按照文档的要求进行四步操作才能获取到用户的基本信息。当然,如果我们只是获取snsapi_base,也就是一个用户的openid,就不需要四步了。
      • 请特别注意:关于网页授权access_token和普通access_token的区别,它们是不一样的。

    实现

    • 前奏:首先构建需要的json对应的bean

      • 通过code换取网页授权access_token,我们将返回的值存在AutoWebParams

        public class AutoWebParams {
        private String access_token;
        private String expires_in;
        private String refresh_token;
        private String openid;
        private String scope;
        //Setter、Getter...
        }
        

      *最终返回的用户信息,我们存储到UserInfo

      public class UserInfo {
      private String openid;
      private String nickname;
      private String sex;
      private String province;
      private String city;
      private String country;
      private String headimgurl;
      private List<String> privilege;
      private String unionid;
      //Setter、Getter...
      }
      
    • 第一步:用户同意授权,获取code,需要引导用户打开此页面

      @WebServlet("/GuideServlet")
      public class GuideServlet extends HttpServlet {
      
          @Override
          protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                  throws ServletException, IOException {
              // 设置编码
              req.setCharacterEncoding("utf-8");
              resp.setContentType("text/html;charset=utf-8");
              resp.setCharacterEncoding("utf-8");
              PrintWriter writer = resp.getWriter();
              /**
               * 第一步:用户同意授权,获取code:https://open.weixin.qq.com/connect/oauth2/authorize
               * ?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE
               * &state=STATE#wechat_redirect
               */
              String redirect_uri = "http://42.96.144.28/WeixinApiDemo/WeixinWebServlet";// 目标访问地址
              redirect_uri = URLEncoder.encode(
                      "http://42.96.144.28/WeixinApiDemo/WeixinWebServlet", "UTF-8");// 授权后重定向的回调链接地址,请使用urlencode对链接进行处理(文档要求)
              // 按照文档要求拼接访问地址
              String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid="
                      + GlobalParams.APPID
                      + "&redirect_uri="
                      + redirect_uri
                      + "&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
              resp.sendRedirect(url);// 跳转到要访问的地址
      
          }
      }
      
    • 第二步:通过code换取网页授权access_token

          /**
           * 第二步:通过code换取网页授权access_token
           */
          String code = req.getParameter("code");// 获取返回码
          // 同意授权
          if (code != null) {
              // 拼接请求地址
              String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
                      + "appid=" + GlobalParams.APPID + "&secret="
                      + GlobalParams.SECERT
                      + "&code=" + code
                      + "&grant_type=authorization_code";
              String json = MyHttpUtils.getReturnJson(url, null);// 拿去返回值
              AutoWebParams autoWebParams = new AutoWebParams();
              Gson gson = new Gson();
              autoWebParams = gson.fromJson(json, new AutoWebParams().getClass());
          }
      
    • 第三步:刷新access_token(如果需要),我们按照文档要求来,使用这一步

          /**
           * 第三步:刷新access_token(如果需要)
           */
          String url2 = "https://api.weixin.qq.com/sns/oauth2/refresh_token?"
                  + "appid=" + GlobalParams.APPID
                  + "&grant_type=refresh_token&refresh_token="
                  + autoWebParams.getRefresh_token();
          String json2 = MyHttpUtils.getReturnJson(url2, null);// 拿去返回值
          AutoWebParams autoWebParams2 = new AutoWebParams();
          Gson gson2 = new Gson();
          autoWebParams2 = gson2
                  .fromJson(json2, new AutoWebParams().getClass());
      
    • 第四步:拉取用户信息(需scope为 snsapi_userinfo)

          /**
           * 第四步:拉取用户信息(需scope为 snsapi_userinfo)
           */
          String url3 = "https://api.weixin.qq.com/sns/userinfo?access_token="
                  + autoWebParams2.getAccess_token()
                  + "&openid="
                  + autoWebParams2.getOpenid() + "&lang=zh_CN";
          String json3 = MyHttpUtils.getReturnJson(url3, null);// 拿去返回值
          UserInfo userInfo = new UserInfo();
          Gson gson3 = new Gson();
          userInfo = gson3.fromJson(new String(json3.getBytes(), "utf-8"),
                  new UserInfo().getClass());
          System.out.println(userInfo);
      
    • 测试显示

          // 显示用户信息
          req.setAttribute("userInfo", userInfo);
          req.getRequestDispatcher("userinfo.jsp").forward(req, resp);
      
    • 显示的userinfo.jsp

      <body>
      <h1>页面太丑,只看内容</h1>
          <table style="margin: 0 auto;">
              <tr>
                  <td>openid(id)</td>
                  <td>${userInfo.openid}</td>
              </tr>
              <tr>
                  <td>nickname(昵称)</td>
                  <td>${userInfo.nickname}</td>
              </tr>
              <tr>
                  <td>sex(性别)</td>
                  <td>
                  <c:if test="${userInfo.sex==0}">未知</c:if>
                  <c:if test="${userInfo.sex==1}">男</c:if>
                  <c:if test="${userInfo.sex==2}">女</c:if>
                  </td>
              </tr>
              <tr>
                  <td>province(省)</td>
                  <td>${userInfo.province}</td>
              </tr>
              <tr>
                  <td>city(市)</td>
                  <td>${userInfo.city}</td>
              </tr>
              <tr>
                  <td>country(国家)</td>
                  <td>${userInfo.country}</td>
              </tr>
              <tr>
                  <td>headimgurl(头像)</td>
                  <td><img alt="头像" style="width: 40px;height: 40px;" src="${userInfo.headimgurl}"></td>
              </tr>
              <tr>
                  <td>privilege(特权,什么意思看文档)</td>
                  <td>
                  <c:forEach items="${userInfo.privilege}" var="p">
                  ${p.String }|
                  </c:forEach>
                  </td>
              </tr>
              <tr>
                  <td>unionid(unionid)</td>
                  <td>${userInfo.unionid}</td>
              </tr>
          </table>
      </body>
      

    测试请在下面的测试号中访问该地址

    http://42.96.144.28/WeixinApiDemo/GuideServlet

    测试的微信号二维码

    这里写图片描述

    技术博客

    这里写图片描述

    源码下载

    http://download.csdn.net/detail/wgyscsf/9508289

    cs