[微信開發] 微信網頁受權Java實現

功能:主要用於在用戶經過手機端微信訪問第三方H5頁面時 獲取用戶的身份信息(openId,暱稱,頭像,所在地等。。)可用來實現微信登陸、微信帳號綁定、用戶身份鑑權等功能。
 
 
開發前的準備:

一、須要有一個公衆號,拿到AppID和AppSecret;web

二、進入公衆號開發者中心頁配置受權回調域名。具體位置:接口權限-網頁服務-網頁帳號-網頁受權獲取用戶基本信息-修改api

    注意,這裏僅需填寫全域名(如www.qq.com、www.baidu.com),勿加 http:// 等協議頭及具體的地址字段; 瀏覽器

    這個域名須要是一個備案過的域名。這個條件比較難辦,幸虧熱心的網友qydev爲咱們無私地提供了一個備案過的域名,咱們能夠經過使用Ngrok來虛擬一個域名映射到本地開發環境,簡直是web開發神器啊。。   微信

    qydev版Ngrok使用說明及下載地址:http://www.qydev.com/  app

    本文以 lovebread.tunnel.qydev.com 域名爲例:工具

       

三、若是嫌手機上測試麻煩,可使用微信官方提供的web開發者工具直接在瀏覽器中進行調試。測試

    前提是須要在微信公衆號中綁定開發者帳號:登陸公衆號-開發者工具-進入web開發者工具-綁定web開發者微信帳號網站

    使用說明及下載地址:https://mp.weixin.qq.com/wiki?action=doc&id=mp1455784140&t=0.7272727088156665&token=&lang=zh_CN#6ui

 
 

受權步驟:url

一、引導用戶進入受權頁面贊成受權,獲取code 

二、經過code換取網頁受權access_token(與基礎支持中的access_token不一樣) 

三、經過網頁受權access_token和openid獲取用戶基本信息

 

Java實現:

一、引導用戶進入受權頁面贊成受權,獲取code 

    這一步其實就是將須要受權的頁面url拼接到微信的認證請求接口裏面,好比須要用戶在訪問頁面 lovebread.tunnel.qydev.com/auth 時進行受權認證,那麼拼接後的受權驗證地址爲:

    https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx88888888&redirect_uri=http://lovebread.tunnel.qydev.com/auth&response_type=code&scope=snsapi_base&state=xxxx_state#wechat_redirect

    這裏面須要替換appid、redirect_uri爲實際的信息。其中的scope參數有兩個值:

    snsapi_base:只能獲取到用戶openid。好處是靜默認證,無需用戶手動點擊認證按鈕,感受上像是直接進入網站同樣。

    snsapi_userinfo:能夠獲取到openid、暱稱、頭像、所在地等信息。須要用戶手動點擊認證按鈕。

 

相關代碼:

   /**
     * 生成用於獲取access_token的Code的Url
     *
     * @param redirectUrl
     * @return
     */
    public String getRequestCodeUrl(String redirectUrl) {
        return String.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect",
                             APPID, redirectUrl, "snsapi_userinfo", "xxxx_state");
    }

 

二、經過第一步獲取的code換取網頁受權access_token(與基礎支持中的access_token不一樣) 

    這一步須要在控制器中獲取微信回傳給咱們的code,經過這個code來請求access_token。

   /**
     * 路由控制
     * 
     * @param request
     * @param code
     * @return 
     */
    @GET
    @Path("auth")
    public Response auth(@Context HttpServletRequest request,
                         @QueryParam("code") String code) {
        Map<String, String> data = new HashMap();
        Map<String, String> result = wechatUtils.getUserInfoAccessToken(code);//經過這個code獲取access_token
        String openId = result.get("openid");
        if (StringUtils.isNotEmpty(openId)) {
            logger.info("try getting user info. [openid={}]", openId);
            Map<String, String> userInfo = wechatUtils.getUserInfo(result.get("access_token"), openId);//使用access_token獲取用戶信息
            logger.info("received user info. [result={}]", userInfo);
            return forward("auth", userInfo);
        }
        return Response.ok("openid爲空").build();
    }
   /**
     * 獲取請求用戶信息的access_token
     *
     * @param code
     * @return
     */
    public Map<String, String> getUserInfoAccessToken(String code) {
        JsonObject object = null;
        Map<String, String> data = new HashMap();
        try {
            String url = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                                       APPID, APPSECRET, code);
            logger.info("request accessToken from url: {}", url);
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            String tokens = EntityUtils.toString(httpEntity, "utf-8");
            Gson token_gson = new Gson();
            object = token_gson.fromJson(tokens, JsonObject.class);
            logger.info("request accessToken success. [result={}]", object);
            data.put("openid", object.get("openid").toString().replaceAll("\"", ""));
            data.put("access_token", object.get("access_token").toString().replaceAll("\"", ""));
        } catch (Exception ex) {
            logger.error("fail to request wechat access token. [error={}]", ex);
        }
        return data;
    }

請求access_token返回樣例:

[result={
"access_token":"OezXcEiiBSKSxW0eoylIeK6mXnzDdGmembMkERL1o1PtpJBEFDaCSwseSTzvZhiKK7Q35O-YctaOFfyJYSPMMEsMq62zw8T6VDljgKJY6g-tCMdTr3Yoeaz1noL6gpJeshMPwEXL5Pj3YBkw",
"expires_in":7200,
"refresh_token":"OezXcEiiBSKSxW0eoylIeK6mXnzDdGmembMkERL1o1PtpJBEFDaCSwseSTOIGqz3ySJRe-lv124wxxtrBdXGd3X1YGysFJnCxjtIE-jaMkvT7aN-12nBa4YtDvr5VSKCU-_UeFFnfW0K3JmZGRA",
"openid":"oN9UryuC0Y01aQt0jKxZXbfe658w",
"scope":"snsapi_userinfo"}]

經過access_token和openid獲取用戶基本信息:
   /**
     * 獲取用戶信息
     *
     * @param accessToken
     * @param openId
     * @return
     */
    public Map<String, String> getUserInfo(String accessToken, String openId) {
        Map<String, String> data = new HashMap();
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN";
        logger.info("request user info from url: {}", url);
        JsonObject userInfo = null;
        try {
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(url);
            HttpResponse httpResponse = httpClient.execute(httpGet);
            HttpEntity httpEntity = httpResponse.getEntity();
            String response = EntityUtils.toString(httpEntity, "utf-8");
            Gson token_gson = new Gson();
            userInfo = token_gson.fromJson(response, JsonObject.class);
            logger.info("get userinfo success. [result={}]", userInfo);
            data.put("openid", userInfo.get("openid").toString().replaceAll("\"", ""));
            data.put("nickname", userInfo.get("nickname").toString().replaceAll("\"", ""));
            data.put("city", userInfo.get("city").toString().replaceAll("\"", ""));
            data.put("province", userInfo.get("province").toString().replaceAll("\"", ""));
            data.put("country", userInfo.get("country").toString().replaceAll("\"", ""));
            data.put("headimgurl", userInfo.get("headimgurl").toString().replaceAll("\"", ""));
        } catch (Exception ex) {
            logger.error("fail to request wechat user info. [error={}]", ex);
        }
        return data;
    }

獲取用戶信息返回樣例:

[result={
"openid":"oN9UryuC0Y01aQt0jKxZXbfe658w",
"nickname":"lovebread",
"sex":1,
"language":"zh_CN",
"city":"",
"province":"",
"country":"中國",
"headimgurl":"http://wx.qlogo.cn/mmopen/bRLXzTf2f6HNfBTd72heAA7vNKsGKvK3dfreewrewsPff9OaMWib0GibbA8daQmNQvQhagtiaicf4vNC5nYU3ia821QQ/0",
"privilege":[]}]
相關文章
相關標籤/搜索