Java微信公众号开发微信网页授权之前端传递code方式获取用户信息

本片博客讲解的网页授权分为两步,前端先传递backUrl(回调地址)到后台网页授权接口,该接口拿到回调地址后组装授权连接,重定向到前端页面,前端页面截取Code,传入后端获取用户信息方法,获取用户信息的方法拿到code后,完成授权流程,获取用户信息完成;

一、网页授权获取用户基本信息

如果用户在微信中(Web微信除外)访问公众号的第三方网页,公众号开发者可以通过此接口获取当前用户基本信息(包括昵称、性别、城市、国家)。利用用户信息,可以实现体验优化、用户来源统计、帐号绑定、用户身份鉴权等功能。本篇文章是记录通过前端传递code参数到后台获取微信用户信息,如果需要纯Java后端获取用户信息,请查看我上一篇博客:  Java微信公众号开发之网页授权获取用户基本信息

注:

注意: “获取用户基本信息接口是在用户和公众号产生消息交互时才能根据用户OpenId获取用户基本信息;而网页授权的方式获取用户基本信息,无需消息交互,只是用户进入到公众号的网页,就可弹出请求用户授权的界面,用户授权后,就可获得其基本信息(此过程甚至不需要用户已经关注公众号。)”;

二、准备工作

1、前提

微信公众号在使用网页授权获取用户信息接口的前提是公众号为服务号,且通过认证在微信公众号请求用户网页授权之前,开发者需要先到公众平台网站的我的服务页中配置授权回调域名
 

2、回调域名设置

设置回调域名之前必须要有内网穿透

2.1、内网穿透

由于微信是本地开发,需要本地开发测试,准备一个内网穿透,将本地127.0.0.1:端口/项目名下所在的服务穿透到外网去,以便能与微信服务器通讯,开发调试;关于内网穿透的工具有很多,详细可以查看:可以实现内网穿透的几款工具,我个人比较推荐Natapp,我使用的是Natapp,Natapp官网购买地址:https://natapp.cn/  ,Natapp内网穿透开启成功后如下图:

2.2、登录微信公众平台设置授权网页回调域名

        在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发—— 接口权限——网页服务——网页授权——点击修改——功能设置——网页授权域名——点击设置按钮”,填写授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头; 

 2.3、填写域名的规范性

       授权回调域名配置规范为全域名,比如需要网页授权的域名为: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鉴权


 

2.4. 设置授权文件

在上一步填写完域名后,注意很重要的一步将以下文件上传至填写域名或路径指向的web服务器(或虚拟主机)的目录(若填写域名,将文件放置在域名根目录下,例如wx.qq.com/MP_verify_x6qyHYovfWrZHcfo.txt;若填写路径,将文件放置在路径目录下,例如wx.qq.com/mp/MP_verify_x6qyHYovfWrZHcfo.txt),并确保可以访问(比如:http://127.0.0.1:8080/MP_verify_x6qyHYovfWrZHcfo.txt)。这里我放置所部属项目的Tomcat服务器的webapp下面的Root目录下面,如果放置位置不正确或者跳过此步,点击保存按钮会无法通过,切记,这是网页授权的必选;

2.5、访问效果证明部署没错:

三、微信网页授权四步流程

1、以snsapi_base为scope发起的网页授权,是用来获取进入页面的用户的openid的,并且是静默授权并自动跳转到回调页  的。用户感知的就是直接进入了回调页(往往是业务页面) 
 2、以snsapi_userinfo为scope发起的网页授权,是用来获取用户的基本信息的。但这种授权会产生一个授权页面,需要用户手动同意,在用户同意后,就可以通过获取用户基本信息的接口获取该用户的基本信息。 如用户的openid,昵称,性别,头像,所在地等我们需要获取用户信息,这里选择就以snsapi_userinfo为scope发起的网页授权

具体而言,网页授权流程分为四步:

1、引导用户进入授权页面同意授权,获取code

2、通过code换取网页授权access_token(与基础支持中的access_token不同)

3、如果需要,开发者可以刷新网页授权access_token,避免过期

4、通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)

以上4步,请详细阅读:微信网页授权官方文档,这里不再累赘

目录

1 第一步:用户同意授权,获取code

2 第二步:通过code换取网页授权access_token

3 第三步:刷新access_token(如果需要)

4 第四步:拉取用户信息(需scope为 snsapi_userinfo)

 

四、开发网页授权接口


  1. 引入微信SDK依赖,该工具类为:WxJavaweixin-java-tools

<!-- 微信框架 参考:https://github.com/Wechat-Group/weixin-java-tools -->
      <dependency>
         <groupId>com.github.binarywang</groupId>
         <artifactId>weixin-java-mp</artifactId>
         <version>3.0.0</version>
      </dependency>

2.创建一个从Controller跳转到测试网页授权的回调地址页面,因为不是前后端分离,所以从后端跳转

 2.1、TestController :


import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import me.chanjar.weixin.mp.api.WxMpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.google.common.collect.Maps;
 
@Controller("mobile/TestController")
@RequestMapping(value = "/mobile/test")
public class TestController extends BaseController {
 
    @Autowired
    private WxMpService wxMpService;
	
 
    @RequestMapping(value = {"/testAuthorize"})
    public String testAuthorize(HttpServletRequest request, HttpServletResponse response, Model model) {
        String openid = (String) request.getSession().getAttribute("openid");
        model.addAttribute("openid", openid);
        return "mobile/modules/app/testAuthorize";
    }
    

	}

 2.2、授权回调页面:testAuthorize.jsp

<%@ page contentType="text/html;charset=UTF-8"%>
<%@ include file="/WEB-INF/views/include/taglib.jsp"%>
<%@ page import="org.apache.shiro.web.filter.authc.FormAuthenticationFilter"%>
<%@ include file="/WEB-INF/views/mobile/modules/app/include/header.jsp"%><!DOCTYPE >
<html>
<head>
<title>测试授权</title>



<script>	


			
    		function aa(){	
    			/* var openid =  GetUrlParam('curoauth');
    			if(openid != ""){
    				alert(openid);
    				return ;
    			} */
    				   				    				
    		     alert('我要授权');
				var backUrl = window.location.href;
				alert("回调地址"+ backUrl);
				console.log("回调:" + backUrl);				   
				//跳转至授权页面
				window.location.href ="http://thinkingcao.natapp1.cc/项目名/api/wechat/authorize"+"?returnUrl="+backUrl;			
				alert('授权完啦');
			   }
    		
    		
    		
    		function GetUrlParam(paraName) {
    		    var url = document.location.toString();
    		    var arrObj = url.split("?");
    		    if (arrObj.length > 1) {
    		      var arrPara = arrObj[1].split("&");
    		      var arr;
    		      for (var i = 0; i < arrPara.length; i++) {
    		        arr = arrPara[i].split("=");
    		        if (arr != null && arr[0] == paraName) {
    		          return arr[1];
    		        }
    		      }
    		      return "";
    		    }
    		    else {
    		      return "";
    		    }
    		  }
 				
    		
			
   		 //判断url后code是否存在,如果不存在说明先执行方法aa(),如果存在,说明需要获取code传到后端,调获取用户信息接口		
   		 var code;    			
   	     if(GetUrlParam('code')) {
   	    	 code=GetUrlParam('code')
   	    	 //设置回调域名这里测试写百度,也可以写当前页面路径
   	    	 var returnUrl = 'http://www.baidu.com';    	        	    	 
   	    	 window.location.href = 'http://xxx.natapp1.cc/项目名/api/wechat/userInfo?code='+code+'&returnUrl='+returnUrl
   	    	    	   	 
   	     }else {
   	    	 aa();
   	     }
    	
    		    	    		     		
    </script>

</head>
<body>
	<div class="wrap">
		<div class="header">
			<a>
				<i class="icon-chevron-left"></i>
			</a>
			<h3>测试网页授权前端通过Code获取</h3>
			<a></a>
		</div>
		<div class="box bg-grey">
			<div class="content">
				<%-- 			<h5>粉丝 openid :${openid}</h5> <br> --%>
				openid :
				<input type="text" name="openid" value="${openid}" />
				userinfo:
				<input type="text" name="wxMpUser" value="${wxMpUser}">
			</div>


		</div>
	</div>
</body>
</html>

2.3、新建ApiWeChatOauthController网页授权后台接口Controller

 ApiWeChatOauthController这个API接口为微信网页授权的完整API,其实我们只用传一个参数“回调地址” 到authorize方法就行, authorize方法组装好网页授权链接后会自动重定向到回调地址页面,页面取出链接地址后的Code参数,然后将Code参数传到userInfo方法,即可网页授权获取用户信息,如以上testAuthorize.jsp页面所示

   网页授权接口代码:

package com.thinkgem.jeesite.modules.app.api.open;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.alibaba.fastjson.JSON;
import com.thinkgem.jeesite.common.utils.HttpTools;

/**
 * <pre>
 * @Desc  提供给第三方授权获取微信用户Openid
 * @author cao_wencao
 * @date 2019年7月26日 上午11:00:17
 * @version V1.0
 * </pre>
 */
@Controller
@RequestMapping(value = "/api/wechat")
@Slf4j
public class ApiWeChatOauthController {

    @Autowired
    private WxMpService wxMpService;
  
    //网页授权方式二
    @GetMapping("/authorize")
    public String authorize(@RequestParam("returnUrl") String returnUrl) throws UnsupportedEncodingException{ 
        String returnUrlEncode =  URLEncoder.encode(returnUrl,"UTF-8");
        String state= "STATE";
        //回调地址
        String requestUrl = "http://thinkingcao.natapp1.cc/greenwx/weixin/test/testAuthorize";
        String redirectURL = wxMpService.oauth2buildAuthorizationUrl(requestUrl, WxConsts.OAuth2Scope.SNSAPI_USERINFO,state);
        log.info("【微信网页授权】获取redirectURL,redirectURL={}", redirectURL);
        return "redirect:" + redirectURL;
    }
 
    @GetMapping("/userInfo")
    public String userInfo(@RequestParam("code") String code,
                         @RequestParam("returnUrl") String returnUrl) throws Exception {
        log.info("【微信网页授权】code={}", code);
        log.info("【微信网页授权】returnUrl={}", returnUrl);
        WxMpUser wxMpUser = null;
        WxMpOAuth2AccessToken wxMpOAuth2AccessToken;
        try {
            wxMpOAuth2AccessToken = wxMpService.oauth2getAccessToken(code);
            String lang = "zh_CN";
            wxMpUser = this.wxMpService.oauth2getUserInfo(wxMpOAuth2AccessToken, lang);          
            log.info("【微信网页授权用户的基本信息】wxMpUser={}", JSON.toJSONString(wxMpUser));
        } catch (WxErrorException e) {
            log.info("【微信网页授权】{}", e);
            throw new Exception(e.getError().getErrorMsg());
        }
        return "redirect:" + returnUrl + "?wxMpUser=" + URLEncoder.encode(JSON.toJSONString(wxMpUser),"UTF-8");
    }



}

4.测试网页授权

   流程:我们先访问页面testAuthorize.jsp,微信开发者工具或手机微信上访问该链接 地址: http://thinkingcao.natapp1.cc/项目名/weixin/test/testAuthorize

                                   

                              

以上4步即走完了网页授权接口,获取到了用户信息

2019-08-05 17:56:39,061 INFO  [modules.app.api.open.ApiWeChatOauthController] - 【微信网页授权】获取redirectURL,redirectURL=https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxbdccd10bef235596&redirect_uri=http%3A%2F%2Fthinkingcao.natapp1.cc%2F项目名%2Fweixin%2Ftest%2FtestAuthorize&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect
2019-08-05 17:56:41,001 INFO  [modules.app.api.open.ApiWeChatOauthController] - 【微信网页授权】code=0611WZTk2sj4zD0GUHQk2F1OTk21WZTG
2019-08-05 17:56:41,001 INFO  [modules.app.api.open.ApiWeChatOauthController] - 【微信网页授权】returnUrl=http://www.baidu.com
2019-08-05 17:56:41,165 INFO  [modules.app.api.open.ApiWeChatOauthController] - 【微信网页授权用户的基本信息】wxMpUser={"city":"墨尔本","country":"澳大利亚","headImgUrl":"http://thirdwx.qlogo.cn/mmopen/vi_32/MSvp05X6xm2It34WTHMiaXBbo2U2EwPBltdQkq3dqWWgfkFuLEvM2iaAOQjJ1qVg1DU69vlrUEj6pMjDjd0srbZA/132","language":"zh_CN","nickname":"曹","openId":"oJIGa0Xlgv1nAtrWLWMlB75ekNDs","privileges":[],"province":"维多利亚","sex":1,"sexDesc":"男"}
发布了329 篇原创文章 · 获赞 232 · 访问量 80万+

猜你喜欢

转载自blog.csdn.net/Thinkingcao/article/details/98500096