前言

博主实际项目中应用场景为,扫描二维码或点击公众号底部菜单栏模块后跳转第三方指定功能模块,第三方系统中使用Filter过滤器进行权限认证,以扫码为例:获取当前扫码微信用户唯一标识,调用系统中相关的方法判断当前扫码用户是否与系统用户绑定,若已绑定则直接跳转功能模块页面,否则引导用户进行第三方系统登录操作,登录完成后将用户输入的系统用户名与用户唯一标识(openid)进行绑定,绑定后跳转功能模块页面,有朋友会问,跳转到功能模块后,前端怎么知道当前的用户对应的是系统的谁,其实选择有很多,可以在判断是否绑定或者登陆成功时,将用户第三方系统用户名存储到session、cookie亦或者直接拼接到顶部url中,此处博主选择的是cookie。

应注意:用户在微信内置浏览器中进行刷新或前端js执行window.reload()方法时,请求再次进入拦截器时无需在重新获取用户微信唯一标识(openid),博主的处理方法为 在请求第一次进入拦截器时,进行“绑定认证” 或者“登录”后,在request的session作用域中存储一个标识,该标识存在的意义是在session未过期的时间内,再次进入拦截器中时如果标识存在并且为true时直接doFilter()跳转。

准备阶段:

  1. 测试公众号申请地址:  申请地址
  2. 微信公众平台技术文档:技术文档
  3. 微信web开发者工具:   下载地址
  4. 可被外网访问的服务器,为方便调试也可使用Sunny-Ngrok的内网穿透服务,将本地tomcat项目发布到外网环境,本文只提供官网地址,如需要可自行百度具体用法。

实施阶段:

  • 微信公众号: 因使用微信网页授权功能,所以需在测试公众号中 网页服务→网页账号中进行相关配置

点击修改按钮,弹出对话框

对话框中填写服务器域名,若使用Sunny-Ngrok填写自定义的域名即可

网页授权时需要的参数信息:微信公众号管理→测试号信息栏

  • 网页授权 
  1. 静默授权:以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面);
  2. 手动授权:以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息;
  • 授权流程
  1. 引导用户进入授权页面同意授权,获取code
  2. 通过code换取网页授权access_token(与基础支持中的access_token不同)
  3. 如果需要,开发者可以刷新网页授权access_token,避免过期
  4. 通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
  • 操作步骤
  1. 请求微信code url:

    https://open.weixin.qq.com/connect/oauth2/authorize
    ?appid=公众号信息中的APPID
    &redirect_uri=授权后重定向的回调链接地址,urlEncode 对链接进行处理(注意重定向的回调地址需和公众号配置中的域名一致,简而言之重定向地址与配置的域名应为同一服务器下)
    &response_type=code(返回类型,请填写code)
    &scope=snsapi_base(此处区分授权方式:snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且, 即使在未关注的情况下,只要用户授权,也能获取其信息 ))
    &state=123(重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节,可用于传递参数)
    #wechat_redirect(无论直接打开还是做页面302重定向时候,必须带此参数)
  2. 接收code:用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE,直接在重定向的方法或拦截器中使用request.getParameter("code")获取即可。
    注意:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟内未使用则自动过期;
  3. 请求微信openid url:
    https://api.weixin.qq.com/sns/oauth2/access_token
    ?appid=公众号信息中的APPID
    &secret=公众号的appsecret
    &code=填写第一步获取的code参数
    &grant_type=authorization_code

    注意:由于公众号的secret和获取到的access_token(微信服务器返回的code)安全级别都非常高,必须只保存在服务器,不允许传给客户端。后续刷新access_token、通过access_token获取用户信息等步骤,也必须从服务器发起。

  4. 接收openid,获取openid时服务器会返回多个参数,只需关注openid即可,openid即为微信用户的唯一标识,获取到微信openid完全可支撑“第三方平台绑定及相关功能”;

应用阶段

以博主项目代码为例


import org.json.JSONException;
import org.json.JSONObject;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;/*** 微信绑定: *    1.引导用户触发绑定功能(微信扫一扫、公众号点击菜单进入、聊天对话框点击url进入)*      请求被过滤器拦截后 首先判断微信code是否为空,如果为空则自动重定向到微信服务器获取微信code;*    2.获取当前用户微信唯一标识:*    ----------------------获取code----------------------------*       (1)用户触发绑定将请求发送到微信服务器*      (2)微信服务器接收请求生成获取用户微信唯一标识的code并回调给本地服务器*    ----------------------获取openid--------------------------*      (3)获取微信返回的code发起请求将code传递到微信服务器*      (4)获取微信返回的openid*    3.判断该用户是否绑定(openid) 调用ehr中对应方法,若已绑定则直接跳转到第6步*    4.跳转登录页面,引导用户完成登录操作*    5.登录成功后获取当前登录人员万信号,调用ehr中对应方法进行绑定(传递:万信号、微信openid)。*    6.跳转初始页面*/
public class CheckLoginFilter implements Filter {/*** 公众号信息中的 appID 及 appsecret*/static final String APPID = "";static final String SECRET = "";/*** filter入口*/@SuppressWarnings("static-access")public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse, FilterChain filterChain)throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) servletRequest;HttpServletResponse response = (HttpServletResponse) servletResponse;//设置是否登录 标识为 falseboolean weixinFlag = false;//session不等于空 则 从域中获取weixinLogin标识if (request.getSession(false) != null) {HttpSession session = request.getSession(false);Boolean flag = (Boolean) session.getAttribute("weixinLogin");weixinFlag = flag != null ? flag : false;}//发起获取code请求 微信服务器重定向后 可直接获取code String code = request.getParameter("code");if (code != null) {System.out.println("---------------------微信code:" + code);}//当用户执行登录状态后重定向 可直接获取openid String openID = request.getParameter("openId");JSONObject jsonObj;//获取当前请求地址 String requestURL = request.getRequestURL().toString();//获取当前请求的参数串 只对get请求生效 String queryString = request.getQueryString()!=null?request.getQueryString():"";//对ajax请求单独处理,返回公众号信息中的APPID 这样前端就可以触发获取微信code操作 if(ajaxDofilterSessionNull(request, response)){//返回isLogin的意义在于 当request中的session失效后,前端则可直接触发重新认证操作 response.setHeader("isLogin",String.valueOf(weixinFlag));response.setHeader("APPID", APPID);} else if (weixinFlag) {//session生效时间内,登录过系统,则weixinFlag标识为true(session存活时间未指定 默认30分钟) filterChain.doFilter(request, response);}//接收返回结果 String result;try {// 当前openid为空时 进行获取code的操作 if (openID == null) {//判断request请求来源是否为微信浏览器boolean isWeChat = isWeChat(request);//通过response重定向微信服 获取微信code if (code == null && isWeChat) {//拼接回调路径 String url = requestURL + "?" + queryString;/*将请求发送到微信服务器,获得code*/String redirectURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APPID + "&redirect_uri=" + URLTool.encodeURL(url) + "&response_type=code&scope=snsapi_base#wechat_redirect";System.out.println("重定向微信服务器地址:" + redirectURL);response.sendRedirect(redirectURL);response.getWriter().close();return;}// 当前openid为空 code不为空时 进行获取微信openid操作if (code != null && !code.isEmpty()) {//拼接获取openid的请求地址String URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";URL = URL.replace("APPID", APPID).replace("SECRET", SECRET).replace("CODE", code);//发起get请求 如果未正常返回,自动重新请求三次 若还未成功则返回nullresult = getUrl(URL, 0);//请求正常返回if (result != null) {System.out.println("result返回结果:" + result);jsonObj = new JSONObject(result);if (jsonObj != null && jsonObj.has("openid")) {System.out.println(" 获取微信openid ");//获取微信openid openID = jsonObj.getString("openid");} else if (jsonObj != null && jsonObj.has("errcode")) {//code失效 - 重新获取-拿到新的code - 获取微信openid String url = requestURL + "?" + queryString;String redirectURL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + APPID + "&redirect_uri=" + URLTool.encodeURL(url) + "&response_type=code&scope=snsapi_base#wechat_redirect";response.sendRedirect(redirectURL);response.getWriter().close();return;}} else {//重连三次后若继续链接失败 则引导用户使用原始登录方式进行验证 /* 自行补充相关代码*/filterChain.doFilter(request, response);}}}//openid不等于空 进行绑定验证if (openID != null && !openID.isEmpty()) {//验证用户是否绑定  自行补充相关代码String isExist = jsonObj.get("success").toString();//未绑定if (isExist.equals("false")) {//未绑定 调用系统绑定方法 ,须传递当前扫码人员的OPENID //用户登录完成后 (博主项目中 登录模块多个系统共用,在登录完成后自动回调到相关业务页面)/*登录相关操作 自行补充*///以获取当前登录人的username(用户名)String username = (String) request.getAttribute("username");if (username != null && !username.isEmpty()) {/*调用绑定方法 博主是将openid 及 username存储了起来  代码自行补充*/String isSave = jsonObj.get("success").toString();//判断是否绑定成功if (isSave.equals("true")) {filterChain.doFilter(request, response);}}} else if (isExist.equals("true")) {/*已绑定 则根据 openid 查询对应 系统中用户名 代码自行补充*///获取用户名String name = jsonObj.getString("username").toString();//设置登录标识 保存到request的session域中HttpSession session = request.getSession();session.setAttribute("weixinLogin", true);try {//将用户名存储到cookie中 供前端获取CookiesUtil cookiesUtil = new CookiesUtil(request, response);cookiesUtil.set("", name.toLowerCase(), -1);} catch (Exception e) {e.printStackTrace();}filterChain.doFilter(request, response);}} else {//网页客户端  自行补充相关登录验证代码filterChain.doFilter(request, response);}} catch (JSONException e) {e.printStackTrace();}}public void destroy() {}public void init(FilterConfig filterConfig) throws ServletException {}/*** @Author 狂野男孩* @Description: TODO 判断是否为微信浏览器* @param request* @Date 14:10 2019-9-10* @return boolean**/private static boolean isWeChat(HttpServletRequest request) {//判断 是否是微信浏览器String userAgent = request.getHeader("user-agent").toLowerCase();if (userAgent.indexOf("micromessenger") > -1) {//微信客户端return true;} else {return false;}}/*** @Author 狂野男孩* @Description: TODO 判断是否是ajax请求* @param request* @param response* @Date 14:10 2019-9-10* @return boolean**/private static boolean ajaxDofilterSessionNull(HttpServletRequest request, HttpServletResponse response) {boolean isAjax = false;if (request.getHeader("x-requested-with") != null && request.getHeader("x-requested-with").equals("XMLHttpRequest")) {// ajax请求isAjax = true;}return isAjax;}/*** 调用对方接口方法* @param path 对方或第三方提供的路径* @param data 向对方或第三方发送的数据,大多数情况下给对方发送JSON数据让对方解析*/public static String getUrl(String path,int requestNumber) {//连接超时后 重连次数if(requestNumber<=3){requestNumber++;try {URL url = new URL(path);//打开和url之间的连接HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");//GET和POST必须全大写conn.setConnectTimeout(3000); // 3秒 连接主机的超时时间(单位:毫秒)conn.setReadTimeout(3000);conn.connect(); //获取URLConnection对象对应的输入流InputStream is = conn.getInputStream();//获取响应BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));String line;StringBuffer sb = new StringBuffer(""); while ((line = reader.readLine()) != null){sb.append(line);  }reader.close();is.close();conn.disconnect();return sb.toString();}catch(ConnectException e){System.out.println("链接超时异常-自动重连"+requestNumber+"次");getUrl(path, requestNumber);}catch (SocketTimeoutException e) {System.out.println("请求超时异常-自动重连"+requestNumber+"次");getUrl(path, requestNumber);}catch (Exception e) {e.printStackTrace();}}return null;}
}

后记

博主在编写过程中主要以项目中实际需求为主,逻辑和部分方法并不适用读者,若在阅读或者开发过程中有疑问或者问题欢迎交流,能实际的帮助到各位,博主心里是开心的。

微信 网页授权/第三方平台账户绑定/微信openid获取相关推荐

  1. 【WEB开发】微信网页授权第三方登录接口(WEB登录)

    https://www.cnblogs.com/xuzhengzong/p/8513269.html 本文链接至:http://blog.csdn.net/hxker/article/details/ ...

  2. 解决vue路由hash模式下,微信网页授权问题

    解决vue路由hash模式下,微信网页授权问题 本人开发负责微信公众号端,菜单都是自定义菜单,然后每个菜单路径都是经过授权如:http://xxxx.com/ceshi/wechat/authoriz ...

  3. PHP 微信网页授权获取用户信息

    最近用到过微信用户授权获取用户信息的功能,在这里记录一下. 因为用户授权要用到认证过的服务号才有权限,而线上正在使用公众号,而开发就有些不方便了,这里可以申请一个微信公众测试号. 1.申请一个微信公众 ...

  4. 微信网页授权(前后端)

    微信网页授权(非静默授权) 最近有个朋友问我,到底那部分是前端做,那部分是后端做.我之前也走了很多弯路,哈哈.下面分享一下我的经验吧.(写的有点粗糙) 微信网页授权官方地址 PS:做微信公众号开发,最 ...

  5. 后盾php文档,后盾PHP微信网页授权接口技术文档

    为什么要学习网页授权接口 如果用户在微信接口通过微信客户端中访问第三方网页,就可以通过网页授权接口来获取用户数据,就是在获取到用户的唯一openid后实现登陆状态 几乎所有的微信站点业务逻辑都需要用户 ...

  6. H5页面使用微信网页授权实现登录认证

    在用H5开发微信公众号页面应用时,往往需要获取微信的用户信息,H5页面在微信属于访问第三方网页,因此通过微信网页授权机制,来获取用户基本信息,此处需要用户确认授权才能获取,用户确认授权后,我们可以认为 ...

  7. ajax 微信code获取_ajax 实现微信网页授权登录的方法

    项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作法,需要采用 ajax 实现微信授权登录. 需求分析 因为本人是一个phper ,所以,微信开发采用的是 EasyWeCha ...

  8. java : 实现微信网页授权,超详细!

    背景 使用微信公众号实现网页授权. 开始 1.微信网页授权的官方文档 微信网页授权 2.申请微信测试公众号 从红框进入申请页面. 填写必要的信息,注意上图红框部分的域名需要可以外网能够访问,微信需要发 ...

  9. php微信授权ajax,ajax 实现微信网页授权登录

    项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作法,需要采用 ajax 实现微信授权登录. 需求分析 因为本人是一个PHPer ,所以,微信开发采用的是 EasyWeCha ...

  10. java ajax 微信网页授权_ajax 实现微信网页授权登录的方法

    AJAX 的 ajax 实现微信网页授权登录的方法 项目背景 因为项目采用前后端完全分离方案,所以,无法使用常规的微信授权登录作法,需要采用 ajax 实现微信授权登录. 需求分析 因为本人是一个ph ...

最新文章

  1. 为什么搜索引擎都上HTTPS?SSL证书竟是如此重要—Vecloud微云
  2. 【信息抽取】如何使用卷积神经网络进行关系抽取
  3. SAP Spartacus storefront 模块的实现位置
  4. Ubuntu上安装Robomongo及添加到启动器
  5. Python学习day01_变量字符串与随机数
  6. 网页中Flash播放器常用参数设置(转)
  7. python压缩算法_用python实现LZ78压缩算法
  8. CSS定位属性(position)
  9. 用python 开发合同管理系统_python3.6+django2.0 一小时学会开发一套学员管理系统demo...
  10. 小笨狼与LLDB的故事
  11. 【栈】实现逆波兰计算器
  12. 计算机配件价格上涨,近期电脑整机和配件涨疯了,但唯独数据恢复不涨价。
  13. SPOOLING系统
  14. 权限管理系统项目文档——Vue前端
  15. 【前端开发遇到到的问题2】文字下方加下划线
  16. c语言注释两种,C语言有几种注释方式
  17. 2022.5.28-YMO青少年奥林匹克数学竞赛复赛(一等奖)
  18. 10分钟带你彻底搞懂服务限流和服务降级
  19. 华为无线设备配置WPA2-802.1X-AES安全策略
  20. tensorflow2.0 新特性 + kaggle练习

热门文章

  1. Marlin固件配置
  2. html5游戏视频UI框架,几款流行的HTML5 UI 框架比较
  3. SCI 文章的DOI查询以及搜索
  4. c语言字符串把小写转换大写字母,c语言将字符串中的小写字母转换成大写字母...
  5. Java深圳工作面试经历(真实经历)!!!
  6. 西方哲学史人物学说时间线
  7. 可编辑的jquery表格插件
  8. 软件测试-正交实验法设计测试用例
  9. CEI Harpoon v1.3-ISO 1CD
  10. 基于神经网络的房价预测,房价预测 神经网络