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

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

作者: 等待未果 | 来源:发表于2017-05-11 11:00 被阅读0次

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

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

    • 注意域名填写不要加 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  使用微信开发工具输入urlalt 使用微信开发工具输入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  页面展示openidalt 页面展示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.经验总结

    相关文章

      网友评论

          本文标题:微信公众号开发网页授权获得OPENID的过滤器

          本文链接:https://www.haomeiwen.com/subject/dkcotxtx.html