微信公众号授权回调用户信息,获取openid

1.--------------------用户授权登录并获取code

授权登录方式有两个,一种为静默授权登录(scope=snsapi_base),一种为非静默授权登录(scope=snsapi_userinfo),区别为静默授权是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)特点:用户无感知,但是只能获取到用户的唯一标示openid和union id,无法拿到用户的微信头像、微信名称等个人信息;非静默授权这种授权需要用户手动同意,并且由于用户同意过,所以无须关注,就可在授权后获取该用户的基本信息。

如果用户同意授权,页面将跳转至 redirect_uri并且携带"?code=CODE&state=STATE"

2.-----------------使用第一步获得的code换取access_token

参数说明
appid=APPID(公众号唯一标识)
secret=SECRET(公众号的appsecret)
code=CODE(第一步获取的code参数)
grant_type=authorization_code(无需更改)

返回结果(json格式数据)
{
"access_token": "e1nYJFpZuehfQH1buzHFZLb7onqs_wT1cudSdy9HRlnaMXFtFpRMNFOA0euK6UxPcItrSNbAQVcXDdthbLJYX0MdH1p7-tkZSKuGqBCxVc0",
"expires_in": 7200,
"refresh_token": "0iVsXn4O1rBCASbO7hx8VNVUVFM1RP2Q4xS0giegd4jlIsJYOjTJNZ0b4Dsh_xcoB02ZZ3bt0WH0a47LvjIEPjWUnESJCZyl6EtY_xYZdVs",
"openid": "o47Fa0mp9SRTf3eiKmqWm69BjG_8",
"scope": "snsapi_userinfo"
}

结果解释
access_token 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
expires_in access_token接口调用凭证超时时间,单位(秒)
refresh_token 用户刷新access_token
openid 用户唯一标识,请注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
scope 用户授权的作用域,使用逗号(,)分隔

3.-----------------使用access_token获取用户信息

-------详情参照微信官方文档,下面贴整合代码 

@RequestMapping(value = "/AuthorizationGetUserInfo.json", produces = "application/json;charset=utf-8", method = RequestMethod.GET)
@ResponseBody
public void AuthorizationGetUserInfo(HttpSession session, HttpServletResponse resp, String code) throws IOException{
        if(code == null){
            log.info("code为空===");
        }
        String url = " https://api.weixin.qq.com/sns/oauth2/access_token";
        String access_tokenUrl = "appid=appid" + "&secret=secret" + "&code=" + code + "&grant_type=authorization_code";//通过code换取网页授权access_token路径
        String result = HttpRequest.sendGet(url, access_tokenUrl);
        Map<String, String> map = WXPayUtil.MapConversion(result);
        String access_token = map.get("access_token");
        String openid = map.get("openid");
        String surl = "https://api.weixin.qq.com/sns/userinfo";
        String userinfoUrl = "access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN";
        String sresult = HttpRequest.sendGet(surl, userinfoUrl);
        Map<String, String> userinfoMap = WXPayUtil.MapConversion(sresult);  //标准json格式的String转json
        String str = userinfoMap.get("nickname");
        try {
            userinfoMap.put("nickname", EmojiUtil.resolveToByteFromEmoji(str));
            log.info("用户头像表情转化成字符" + userinfoMap.get("nickname"));

        } catch (Exception e) {
            log.info("用户信息拉取失败=========================");
            log.info("用户信息拉取失败=========================" + e.getMessage());
        }
        String suOpenid = vipMapperService.ByOpenIdQueVip(openid);//查询用户表中的openid
        log.info("session的ID" + session.getId());
        if (suOpenid != null && suOpenid != "") {
            User user = vipMapperService.selectVipInfo(userinfoMap);

            if (!user.getUuser().equals(userinfoMap.get("nickname"))) {
                userinfoMap.put("nickname", user.getUuser());//修改为新的昵称
            }
            if (!user.getHeadimgurl().equals(userinfoMap.get("headimgurl"))) {
                userinfoMap.put("headimgurl", user.getHeadimgurl());//修改为新的头像
            }
                Integer Upresult = vipMapperService.ByWXUpVip(userinfoMap);//修改会员
            if (Upresult < 0) {
                log.info("修改会员失败了!");
            }
        } else {
            //该openid用户表中不存在,新增用户
            Integer Addresult = vipMapperService.AddVip(userinfoMap);
            if (Addresult < 0) {
                log.info("新增会员失败了===!");
            }
        }
            Integer Uid = vipMapperService.ByOpenIdQuUid(openid);
            Cookie cookie = new Cookie("Uid", String.valueOf(Uid));
            resp.addCookie(cookie);
            resp.sendRedirect(NowData.PROTOCOL + NowData.DOMAIN + "/WeChatpn/index.html#/mall");
    }
---------------------------------utils
/**
 * 向指定URL发送GET方法的请求
 * 
 * @param url
 *            发送请求的URL
 * @param param
 *            请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
 * @return URL 所代表远程资源的响应结果
 */
public static String sendGet(String url, String param) {
   String result = "";
   BufferedReader in = null;
   try {
      String urlNameString = url + "?" + param;
      URL realUrl = new URL(urlNameString);
      // 打开和URL之间的连接
      URLConnection connection = realUrl.openConnection();
      // 设置通用的请求属性
      connection.setRequestProperty("accept", "*/*");
      connection.setRequestProperty("connection", "Keep-Alive");
      connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
      // 建立实际的连接
      connection.connect();
      // 获取所有响应头字段
      Map<String, List<String>> map = connection.getHeaderFields();
      // 遍历所有的响应头字段
      for (String key : map.keySet()) {
         //System.out.println(key + "--->" + map.get(key));
      }
      // 定义 BufferedReader输入流来读取URL的响应
      in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
      String line;
      while ((line = in.readLine()) != null) {
         result += line;
      }
   } catch (Exception e) {
      System.out.println("发送GET请求出现异常!" + e);
      e.printStackTrace();
   }
   // 使用finally块来关闭输入流
   finally {
      try {
         if (in != null) {
            in.close();
         }
      } catch (Exception e2) {
         e2.printStackTrace();
      }
   }
   return result;
}
/**
 * String转Map<String, String>
 * map
 *
 * @return
 */
public static Map<String, String> MapConversion(String str) {
    Map<String, Object> map = JSON.parseObject(str);
    Map<String, String> NewMap = new HashMap<String, String>();
    for (String string : map.keySet()) {
        NewMap.put(string, map.get(string).toString());
    }
    return NewMap;
}
/**
 * 利用正则表达式判断str是否存在表情字符
 * @param str
 * @return
 */
public static String resolveToByteFromEmoji(String str) {
   Pattern pattern = Pattern
         .compile("[^(u2E80-u9FFF\w\s`~!@#\$%\^&\*\(\)_+-?()——=\[\]{}\|;。,、《》”:;“!……’:‘"<,>\.?/\\*)]");
   Matcher matcher = pattern.matcher(str);
   StringBuffer sb2 = new StringBuffer();
   while (matcher.find()) {
      matcher.appendReplacement(sb2, encode(matcher.group(0)));
   }
   matcher.appendTail(sb2);
   //将分隔符 替换成 得到的内容就是 u1245
   return sb2.toString().replace("&ns;","\");
}
境随心转而悦,心随境转而烦
原文地址:https://www.cnblogs.com/tomingto/p/11281314.html