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

1.填写授权回调页面域名:

1.1获取微信公众平台测试账号

alt 获取微信公众平台测试账号
alt 获取微信公众平台测试账号

1.2对帐号进行接口配置填写

alt 对帐号进行接口配置填写
alt 对帐号进行接口配置填写

1.3填写授权回调页面域名

  • 注意域名填写不要加 http:// 或者 https://
    alt 填写授权回调页面域名
    alt 填写授权回调页面域名

2授权成功获得Openid

2.1用户同意授权,获取code

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

https://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配置:

     <filter>
         <filter-name>openidFilter</filter-name>
         <filter-class>com.weixin.oauth.filter.OpenidFilter</filter-class>
     </filter>
     <filter-mapping>
         <filter-name>openidFilter</filter-name>
         <url-pattern>/*</url-pattern>
         <dispatcher>1</dispatcher>
     </filter-mapping>
    
  • 直接在微信Web开发工具输入需要封装的url:


    alt  使用微信开发工具输入url
    alt 使用微信开发工具输入url
  • 过滤修改后的url:

     https://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

  • 之后会进入授权页面:
alt  用户进行授权
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的请求连接: https://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 = "https://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 = "https://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:https://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:

alt  页面展示openid
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.经验总结

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260

推荐阅读更多精彩内容