目录

前言

网页授权流程分为四步:

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

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

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

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

行了,一步步来吧,在这之前要在权限列表中设置回调域名。

微信公众号开发 - 14.微信网页授权获取基本用户资料

微信公众号开发 - 14.微信网页授权获取基本用户资料

用户同意授权,获取code

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

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

这里注意的是,获取用户资料scope一定要用snsapi_userinfo,否则拿到的CODE不能获取微信公众号开发 - 14.微信网页授权获取基本用户资料

若提示“该链接无法访问”,请检查参数是否填写错误,是否拥有scope参数对应的授权作用域权限。

微信公众号开发 - 14.微信网页授权获取基本用户资料

如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。这里我们需要的就是code后面带的参数。

网页开发的话可以在回调页面通过request.getparameter获取到code值,这里我就直接在跳转的链接中拿到CODE值,就不写代码了。

code说明:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

通过code换取网页授权access_token

首先请注意,这里通过code换取的是一个特殊的网页授权access_token,与基础支持中的access_token(该access_token用于调用其他接口)不同。公众号可通过下述接口来获取网页授权access_token。如果网页授权的作用域为snsapi_base,则本步骤中获取到网页授权access_token的同时,也获取到了openid,snsapi_base式的网页授权流程即到此为止。

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

微信公众号开发 - 14.微信网页授权获取基本用户资料

微信公众号开发 - 14.微信网页授权获取基本用户资料

实体

package cn.notemi.po;

/**
 * Title:UserAccessToken
 * Description:网页授权获取用户时需要的AccessToken
 *
 * @author Flicker
 * @create 2017-07-28 下午 3:00
 **/
public class WeixinOauth2Token extends AccessToken{
    private String refresh_token;
    private String openid;
    private String scope;

    public String getRefresh_token() {
        return refresh_token;
    }

    public void setRefresh_token(String refresh_token) {
        this.refresh_token = refresh_token;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}

获取access_token和openid

/**
     * 获取网页授权需要的accesstoken和openid
     * @param code
     * @return
     * @throws Exception
     */
    public static WeixinOauth2Token getUserAccessToken(String code){
        WeixinOauth2Token token = new WeixinOauth2Token();
        String url = SNS_ACCESS_TOKEN_URL.replace("APPID",APPID).replace("SECRET",APPSECRET).replace("CODE",code);
        System.out.println("url:"+url);
        JSONObject jsonObject = null;
        try {
            jsonObject = doGetStr(url);
            logger.info("获取accesstoken和openid:"+jsonObject.toString());
            if (jsonObject != null){
                token.setAccess_token(jsonObject.getString("access_token"));
                token.setOpenid(jsonObject.getString("openid"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("code已过期");
        }
        return token;
    }

刷新access_token(如果需要)

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

我这里暂时不需要,略。

拉取用户信息

微信公众号开发 - 14.微信网页授权获取基本用户资料

返回参数

微信公众号开发 - 14.微信网页授权获取基本用户资料

实体

package cn.notemi.po;

import java.util.List;

/**
 * Title:SNSUserInfo
 * Description:用户基本信息
 *
 * @author Flicker
 * @create 2017-07-28 下午 1:37
 **/
public class SNSUserInfo {
    // 用户的标识
    private String openid;
    // 昵称
    private String nickname;
    // 用户的性别(1是男性,2是女性,0是未知)
    private int sex;
    // 用户所在国家
    private String country;
    // 用户所在省份
    private String province;
    // 用户所在城市
    private String city;
    // 用户头像
    private String headimgurl;
    //用户特权限信息
    private List<String> privilegeList;

    public List<String> getPrivilegeList() {
        return privilegeList;
    }

    public void setPrivilegeList(List<String> privilegeList) {
        this.privilegeList = privilegeList;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getHeadimgurl() {
        return headimgurl;
    }

    public void setHeadimgurl(String headimgurl) {
        this.headimgurl = headimgurl;
    }
}

获取用户资料

/**
     * 获取用户资料
     * @param accessToken
     * @param openId
     * @return
     */
    public static SNSUserInfo getUserInfo(String accessToken, String openId){
        SNSUserInfo weixinUserInfo = null;
        // 拼接请求地址
        String requestUrl = SNS_USER_INFO_URL.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId);
        logger.info("getUserInfo-url:"+requestUrl);
        // 获取用户信息
        JSONObject jsonObject = null;
        try {
            jsonObject = doGetStr(requestUrl);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (null != jsonObject) {
            try {
                weixinUserInfo = new SNSUserInfo();
                // 用户的标识
                weixinUserInfo.setOpenid(jsonObject.getString("openid"));
                // 昵称
                weixinUserInfo.setNickname(jsonObject.getString("nickname"));
                // 用户的性别(1是男性,2是女性,0是未知)
                weixinUserInfo.setSex(jsonObject.getInt("sex"));
                // 用户所在国家
                weixinUserInfo.setCountry(jsonObject.getString("country"));
                // 用户所在省份
                weixinUserInfo.setProvince(jsonObject.getString("province"));
                // 用户所在城市
                weixinUserInfo.setCity(jsonObject.getString("city"));
                // 用户头像
                weixinUserInfo.setHeadimgurl(jsonObject.getString("headimgurl"));
                logger.info("用户信息返回值:"+jsonObject.toString());
            } catch (Exception e) {
                System.out.println("获取用户信息失败,错误信息:"+jsonObject.toString());
            }

        }
        return weixinUserInfo;
    }

测试

/**
         * 获取用户信息
         */
        WeixinOauth2Token userAccessToken = WeixinUtil.getUserAccessToken("021qxHHv1GNxBd0bDjIv1jdFHv1qxHHK");
        System.out.println("getToken:"+userAccessToken.getAccess_token());
        System.out.println("openid"+userAccessToken.getOpenid());

        SNSUserInfo user = WeixinUtil.getUserInfo(userAccessToken.getAccess_token(), userAccessToken.getOpenid());
        System.out.println("OpenID:" + user.getOpenid());
        System.out.println("昵称:" + user.getNickname());
        System.out.println("性别:" + user.getSex());
        System.out.println("国家:" + user.getCountry());
        System.out.println("省份:" + user.getProvince());
        System.out.println("城市:" + user.getCity());
        System.out.println("头像:" + user.getHeadimgurl());

微信公众号开发 - 14.微信网页授权获取基本用户资料

源代码

Weixin.rar