spring boot + vue 微信网页授权,获取用户信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/woshimeihuo/article/details/88727789

最近都在和微信的网页授权做斗争,由于第一次接触,所以道路比较曲折,不过,现在已经好啦,详细记录一下

需求: 公众号的网页授权并获取用户信息(包括unionid),unionid的获取前提是,同一开发平台的应用
开发前准备: 请先阅读微信公众平台技术文档

1.阅读网页授权开发文档
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

2.获取微信凭证appidappsecret
https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

3.下载微信web开发者工具
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1455784140

4.修改本地hosts,最底下添加 127.0.0.1 www.t.cn,用来指向本地,设置回调地址时可用
路径: C:\Windows\System32\drivers\etc

5.vue的端口需要是80端口

6.在测试账号中找到并修改,我们hosts中修改的地址
在这里插入图片描述
在这里插入图片描述

开发思路
1.前端调用/user/oauth接口,后端传回微信授权地址
2.前端跳转授权地址,并获取回调地址后带的code
3.使用code,请求/user/publicInfo接口,获取用户信息

开始开发
1./user/oauth接口

	/**
    * 拼接公众号用户授权地址,并回传给前端
    * params callbackUrl 前端回调地址
    * @return
    */
   @GetMapping(value = "/user/oauth")
   public ResponseWrapper auth(@RequestParam Map<String, Object> params){
       String callbackUrl = params.get("callbackUrl").toString();
       Map<String, String> param = new HashMap<>();
       param.put("appid", H5Configuration.getH5Configuration().getAppId());
       param.put("redirect_uri", callbackUrl);
       param.put("response_type", "code");
       param.put("scope", "snsapi_userinfo");
       String url = "";
       try {
           url = H5Configuration.getH5Configuration().getAuthUrl()+"?"+"appid="+H5Configuration.getH5Configuration().getAppId()+"&redirect_uri="+callbackUrl+"&response_type=code&scope=snsapi_userinfo#wechat_redirect";
       } catch (Exception e) {
           e.printStackTrace();
       }
       Map<String,String> result = new HashMap<>();
       result.put("url",url);
       return  ResponseWrapper.ok(result);
   }

2.前端获取授权地址

	  mounted(){
		  //调用获取凭证方法
          this.getTicket();
      },
      methods:{
          getTicket(){
              let self = this;
              this.$vux.loading.show({
                  text: '加载中...'
              })
              // 获取回调url中的参数code
              let objData = this.GetRequest();
              if(objData && objData.code){
                  let params = {
                     code:objData.code
                  }
                  //根据code向后端获取当前授权用户信息
                self.$axios.userPublicInfo(params).then(res=>{
                    if(res.code == 200){
                          let {ticket} = res.data;
                          //存储用户信息
                          setSessionStore("userDataInfo",res.data);
                          if(ticket){
                              setSessionStore("userTicket",ticket);
                              //前往首页
                              self.goRoute("Home");
                          }
                      }
                }) 
                  return
              }else{
                  //此处写公众号配置的回调地址
                  let jumpToUrl = window.location.protocol+"//"+window.location.host;
                  let params = {
                  	//回调url编码
                      callbackUrl:encodeURIComponent(jumpToUrl)
                  }
                  self.$axios.userOauth(params).then(res=>{
                  	//跳转微信授权页面
                      window.location.href = res.data.url 
                  })
                
              }
          },
          goRoute(name){
              this.$router.push({name:name})
          },
          GetRequest(){ //获取回调url及参数
              var url = location.search; //获取url中"?"符后的字串  
              var theRequest = new Object();  
              if (url.indexOf("?") != -1) {  
                  var str = url.substr(1);  
                  var strs = str.split("&");  
                  for(var i = 0; i < strs.length; i ++) {  
                      theRequest[strs[i].split("=")[0]]=unescape(strs[i].split("=")[1]);  
                  }  
              }  
              return theRequest;
          }
      },

3.根据code,获取用户信息,/user/publicInfo接口

	/**
     * 公众号获取用户信息
     * @return
     */
    @GetMapping(value = "/user/publicInfo")
    @ResponseBody
    public ResponseWrapper getAccessToken(@RequestParam Map<String, Object> params) {
        String code = params.get("code").toString();
        return userService.publicUserInfo(code);
    }
	@Override
	public ResponseWrapper publicUserInfo(String code) {
	   //根据code获取accesstoken
	  JSONObject resultH5 =  H5Util.getAccessToken(code);
	  if(resultH5.containsKey("errmsg")){
	      return ResponseWrapper.error("accessToken信息获取失败");
	  }
	  String accessToken = resultH5.getString("access_token");
	  String openid = resultH5.getString("openid");
	  //根据access_token和openid获取用户信息
	   JSONObject userInfoJSON = H5Util.getUserInfo(accessToken,openid);
	   if(userInfoJSON.containsKey("errmsg")){
	       return ResponseWrapper.error("userInfo信息获取失败");
	   }
	   User user = new User();
	   String token = null;
	   if(userInfoJSON.containsKey("openid")){
	   	//因为是测试号,所以,是没有unionid的
	       String unionId = userInfoJSON.containsKey("unionId")==false?"11111111":userInfoJSON.getString("unionId");
	       String avatarUrl = userInfoJSON.getString("headimgurl");
	       String nickName = userInfoJSON.getString("nickname");
	       Integer gender = userInfoJSON.getInteger("sex"); 
	       token = JWTApiUtil.sign(user);
	       JSONObject result = new JSONObject();
	       result.put("sex", sex);
	       result.put("avatarUrl", avatarUrl);
	       result.put("nickName", nickName);
	       return ResponseWrapper.ok(result);
	   }
	   return ResponseWrapper.error("获取用户信息失败");
	}

4.H5Util工具类

/**
 * 公众号工具类
 * @author bright
 * @date 2019/3/13
 */
public class H5Util {

    private static final Logger logger = LoggerFactory.getLogger(MiniProgramUtil.class);

    /**
     * 第一步:获取code,发起授权
     * 第二步:通过code换取网页授权access_token(与基础支持中的access_token不同)
     */
    public static JSONObject getAccessToken(String code) {
        Map<String, String> params = new HashMap<>();
        params.put("appid", H5Configuration.getH5Configuration().getAppId());
        params.put("secret", H5Configuration.getH5Configuration().getSecret());
        params.put("code", code);
        params.put("grant_type", "authorization_code");
        JSONObject resultObj = new JSONObject();
        try {
            String url = HttpUtils.buildUrl(H5Configuration.getH5Configuration().getAccessToken(), "", params);
            HttpResponse response = null;
            response = HttpUtils.doGet(url);
            BufferedReader b = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"), 8 * 1024);
            String line = b.readLine();
            resultObj = JSONObject.parseObject(line);
            if (resultObj.containsKey("errmsg")) {
                String errmsg = resultObj.getString("errmsg");
                if (!resultObj.getString("errcode").equals("0")) {
                    logger.info("获取access_token失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultObj;
    }

    /**
     * 第三步:如果需要,开发者可以刷新网页授权access_token,避免过期
     * 第四步:通过网页授权access_token和openid获取用户基本信息(支持UnionID机制)
     */
    public static JSONObject getUserInfo(String accessToken, String openId) {
        Map<String, String> params = new HashMap<>();
        params.put("access_token", accessToken);
        params.put("openid", openId);
        params.put("lang", "zh_CN");
        JSONObject resultObj = new JSONObject();
        try {
            String url = HttpUtils.buildUrl(H5Configuration.getH5Configuration().getUserInfo(), "", params);
            HttpResponse response = null;
            response = HttpUtils.doGet(url);
            BufferedReader b = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"), 8 * 1024);
            String line = b.readLine();
            resultObj = JSONObject.parseObject(line);
            if (resultObj.containsKey("errmsg")) {
                String errmsg = resultObj.getString("errmsg");
                if (!resultObj.getString("errcode").equals("0")) {
                    logger.info("获取unionid失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultObj;
    }
}

效果图 在开发工具中输入www.t.cn即可
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/woshimeihuo/article/details/88727789
今日推荐