0.官方文档

微信网页授权步骤 --> 传送门

1 第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
5 附:检验授权凭证(access_token)是否有效

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

组装鉴权链接—>
在确保微信公众账号拥有授权作用域(scope参数)的权限的前提下(服务号获得高级接口后,默认拥有scope参数中的snsapi_base和snsapi_userinfo),引导关注者打开如下页面(直接把url贴到微信,打开链接即可):

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect

若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。
首先做一个你内网穿透:
https://ray.ngrok.xiaomiqiu.cn 是我本地做的一个内网穿透(小米球),映射到本地6001服务。
在这里插入图片描述

我的:

https://open.weixin.qq.com/connect/oauth2/authorize?appid="+ appid + "&redirect_uri=https%3a%2f%2fray.ngrok.xiaomiqiu.cn%2fwechat%2fgetCode&response_type=code&scope=snsapi_userinfo&state=xxx#wechat_redirect
注意:回调redirect_uri的值需要encode-->
https://ray.ngrok.xiaomiqiu.cn/wechat/getCode  -->utf8-encode--> https%3a%2f%2fray.ngrok.xiaomiqiu.cn%2fwechat%2fgetCode

用户点击该url—>微信跳转回调我们设置的redirect_uri(https://ray.ngrok.xiaomiqiu.cn/wechat/getCode).
那么我们在
在这里插入图片描述
在里面我们可以获取微信传递给我们的code。

2.通过code换取网页授权access_token

    -->>>>>>>>>>获取code后,请求以下链接请求获取access_token
    public static final String WEB_GET_ACCESS_REQ_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";

    public static WxOauth2Token getOauth2AccessToken(String appId, String appSecret, String code) {
    	WxOauth2Token wat = null;
        // 拼接请求地址
        String requestUrl = WEB_GET_ACCESS_REQ_URL;
        requestUrl = requestUrl.replace("APPID", appId);
        requestUrl = requestUrl.replace("SECRET", appSecret);
        requestUrl = requestUrl.replace("CODE", code);
        // 获取网页授权凭证
//        JSONObject jsonObject = CommonUtil.httpsRequest(requestUrl, "GET", null);
        JSONObject jsonObject = WxUtil.doGetStr(requestUrl);
        if (null != jsonObject) {
            try {
                wat = new WxOauth2Token();
                wat.setAccessToken(jsonObject.getString("access_token"));
                wat.setExpiresIn(jsonObject.getInteger("expires_in"));
                wat.setRefreshToken(jsonObject.getString("refresh_token"));
                wat.setOpenId(jsonObject.getString("openid"));
                wat.setScope(jsonObject.getString("scope"));
            } catch (Exception e) {
                wat = null;
                int errorCode = jsonObject.getInteger("errcode");
                String errorMsg = jsonObject.getString("errmsg");
                logger.error("获取网页授权凭证失败 errcode:{} errmsg:{}" + errorCode + errorMsg);
            }
        }
        return wat;
    }

    WxOauth2Token weixinOauth2Token = WxWebUtil.getOauth2AccessToken(WxAuth.instance().getAppid(), WxAuth.instance().getAppsec(), code);

现在得到了access_token,可以取到用户信息了!!!!!

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

由于access_token拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。

获取第二步的refresh_token后,请求以下链接获取access_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
具体参考官方文档。

4.拉取用户信息(需scope为 snsapi_userinfo)

    /**
     * 通过网页授权获取用户信息
     * 
     * @param accessToken 网页授权接口调用凭证
     * @param openId 用户标识
     * @return WxWebUserInfo
     */
	@SuppressWarnings({ "deprecation", "unchecked" })
	public static WxWebUserInfo getSNSUserInfo(String accessToken, String openId) {
		WxWebUserInfo snsUserInfo = null;
		// 拼接请求地址
		String requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID";
		requestUrl = requestUrl.replace("ACCESS_TOKEN", accessToken).replace(
				"OPENID", openId);
		// 通过网页授权获取用户信息
		JSONObject jsonObject = WxUtil.doGetStr(requestUrl);
		if (null != jsonObject) {
			try {
				snsUserInfo = new WxWebUserInfo();
				// 用户的标识
				snsUserInfo.setOpenId(jsonObject.getString("openid"));
				// 昵称
				snsUserInfo.setNickname(jsonObject.getString("nickname"));
				// 性别(1是男性,2是女性,0是未知)
				snsUserInfo.setSex(jsonObject.getInteger("sex"));
				// 用户所在国家
				snsUserInfo.setCountry(jsonObject.getString("country"));
				// 用户所在省份
				snsUserInfo.setProvince(jsonObject.getString("province"));
				// 用户所在城市
				snsUserInfo.setCity(jsonObject.getString("city"));
				// 用户头像
				snsUserInfo.setHeadImgUrl(jsonObject.getString("headimgurl"));
				// 用户特权信息
//				JSONArray.parseArray()
//				snsUserInfo.setPrivilegeList(JSONArray.toList(jsonObject.getJSONArray("privilege"), List.class));
			} catch (Exception e) {
				snsUserInfo = null;
				int errorCode = jsonObject.getInteger("errcode");
				String errorMsg = jsonObject.getString("errmsg");
				logger.error("获取用户信息失败 errcode:{} errmsg:{}" +  errorCode + errorMsg);
			}
		}
		return snsUserInfo;
	}

    //通过第二步,获取accesstoken和openid
    WxOauth2Token weixinOauth2Token = WxWebUtil.getOauth2AccessToken(WxAuth.instance().getAppid(), WxAuth.instance().getAppsec(), code);
    // 网页授权接口访问凭证
    String accessToken = weixinOauth2Token.getAccessToken();
    // 用户标识
    openId = weixinOauth2Token.getOpenId();
    // 获取用户信息
    WxWebUserInfo snsUserInfo = WxWebUtil.getSNSUserInfo(accessToken, openId);

结尾处,重定向到vue前端首页并带上唯一标志:

    /**
     * 鉴权回调
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
	@RequestMapping("/getCode")
	public ModelAndView getCode(HttpServletRequest request) {
		String code = request.getParameter("code");
		String state = request.getParameter("state");
        String openId = GlobalConstant.Symbol.EMPTY;
		// 用户同意授权
        if (!"authdeny".equals(code)) {
            // 获取网页授权access_token
            WxOauth2Token weixinOauth2Token = WxWebUtil.getOauth2AccessToken(WxAuth.instance().getAppid(), WxAuth.instance().getAppsec(), code);
            // 网页授权接口访问凭证
            String accessToken = weixinOauth2Token.getAccessToken();
            // 用户标识
            openId = weixinOauth2Token.getOpenId();
            // 获取用户信息
            WxWebUserInfo snsUserInfo = WxWebUtil.getSNSUserInfo(accessToken, openId);

            if (ObjUtils.isNotEmpty(redisDAO)) {
                redisDAO.set(RedisKeyUtil.getPartnerUserAuthInfoKey(openId), weixinOauth2Token, RedisKeyUtil.EXPIRE_TIME_SEC_MAX);
            }

            log.info("获取用户信息: " + snsUserInfo.toString());

            return null;
        }

        // 重定向到vue前端首页并带上唯一标志, 这里你可以带上加密后的token,然后前后端识别就使用该token进行用户身份验证识别,
        //我在此处简单处理,就直接用openid,然后前端展示首页的时候,截取url里面的内容:openid,然后前端vue就获取到了openid了。
        //shaw.ngrok.xiaomiqiu.cn是我做的一个内网穿透,指向前端vue页面。
        String url_to = "http://shaw.ngrok.xiaomiqiu.cn/vue-project?openid=" + openId;


        return new ModelAndView(new RedirectView(url_to));
	}

该链接一般设置到服务号的菜单栏里面,设置微信菜单栏,后期发布文章。
我们在手机端点击开那个鉴权链接,经过上面的操作之后,就会重定向到后台设置的跳转到vue项目首页。首页通过openid获取服务器数据。

5.前端部分:

我做的是将前端打包放到tomcat下
在这里插入图片描述

webapps\vue-project
–static
–index.html
然后tomcat(端口8080)跑起来,做一个内网穿透
在这里插入图片描述
http://shaw.ngrok.xiaomiqiu.cn --> 127.0.0.1:8080
服务端重定向到这个地址,那么前端vue的页面就展示到微信里面了。
OK!

Logo

前往低代码交流专区

更多推荐