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

来源:互联网 发布:儿童编程教育市场分析 编辑:程序博客网 时间:2024/05/23 14:30

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填写授权回调页面域名


  • 注意域名填写不要加 http:// 或者 https://
    %u586B%u5199%u6388%u6743%u56DE%u8C03%u9875%u9762%u57DF%u540D
    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:

    %u4F7F%u7528%u5FAE%u4FE1%u5F00%u53D1%u5DE5%u5177%u8F93%u5165url
    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

  • 之后会进入授权页面:
%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的请求连接: 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:

%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.经验总结

阅读全文
0 0