1. 程式人生 > >微信網頁授權—獲取使用者資訊

微信網頁授權—獲取使用者資訊

開發前必讀

關於網頁授權回撥域名的說明
1、在微信公眾號請求使用者網頁授權之前,開發者需要先到公眾平臺官網中的“開發 - 介面許可權 - 網頁服務 - 網頁帳號 - 網頁授權獲取使用者基本資訊”的配置選項中,修改授權回撥域名。請注意,這裡填寫的是域名(是一個字串),而不是URL,因此請勿加 http:// 等協議頭;
2、授權回撥域名配置規範為全域名,比如需要網頁授權的域名為:www.qq.com,配置以後此域名下面的頁面http://www.qq.com/music.htmlhttp://www.qq.com/login.html 都可以進行OAuth2.0鑑權。但http://pay.qq.com

http://music.qq.comhttp://qq.com無法進行OAuth2.0鑑權
3、如果公眾號登入授權給了第三方開發者來進行管理,則不必做任何設定,由第三方代替公眾號實現網頁授權即可
關於網頁授權的兩種scope的區別說明
1、以snsapi_base為scope發起的網頁授權,是用來獲取進入頁面的使用者的openid的,並且是靜默授權並自動跳轉到回撥頁的。使用者感知的就是直接進入了回撥頁(往往是業務頁面)
2、以snsapi_userinfo為scope發起的網頁授權,是用來獲取使用者的基本資訊的。但這種授權需要使用者手動同意,並且由於使用者同意過,所以無須關注,就可在授權後獲取該使用者的基本資訊。
3、使用者管理類介面中的“獲取使用者基本資訊介面”,是在使用者和公眾號產生訊息互動或關注後事件推送後,才能根據使用者OpenID來獲取使用者基本資訊。這個介面,包括其他微信介面,都是需要該使用者(即openid)關注了公眾號後,才能呼叫成功的。
關於網頁授權access_token和普通access_token的區別

1、微信網頁授權是通過OAuth2.0機制實現的,在使用者授權給公眾號後,公眾號可以獲取到一個網頁授權特有的介面呼叫憑證(網頁授權access_token),通過網頁授權access_token可以進行授權後接口呼叫,如獲取使用者基本資訊;
2、其他微信介面,需要通過基礎支援中的“獲取access_token”介面來獲取到的普通access_token呼叫。
關於UnionID機制
1、請注意,網頁授權獲取使用者基本資訊也遵循UnionID機制。即如果開發者有在多個公眾號,或在公眾號、移動應用之間統一使用者帳號的需求,需要前往微信開放平臺(open.weixin.qq.com)繫結公眾號後,才可利用UnionID機制來滿足上述需求。
2、UnionID機制的作用說明:如果開發者擁有多個移動應用、網站應用和公眾帳號,可通過獲取使用者基本資訊中的unionid來區分使用者的唯一性,因為同一使用者,對同一個微信開放平臺下的不同應用(移動應用、網站應用和公眾帳號),unionid是相同的。
關於特殊場景下的靜默授權

1、上面已經提到,對於以snsapi_base為scope的網頁授權,就靜默授權的,使用者無感知;
2、對於已關注公眾號的使用者,如果使用者從公眾號的會話或者自定義選單進入本公眾號的網頁授權頁,即使是scope為snsapi_userinfo,也是靜默授權,使用者無感知。
具體而言,網頁授權流程分為四步:
1、引導使用者進入授權頁面同意授權,獲取code
2、通過code換取網頁授權access_token(與基礎支援中的access_token不同)
3、如果需要,開發者可以重新整理網頁授權access_token,避免過期
4、通過網頁授權access_token和openid獲取使用者基本資訊(支援UnionID機制)
以上在微信介面文件中都有詳細說明,下面開始配置開發。

第一步 配置回撥域名

在微信公眾平臺 “開發 - 介面許可權 - 網頁服務 - 網頁帳號 - 網頁授權獲取使用者基本資訊”的配置選項中,修改授權回撥域名。
這裡寫圖片描述

由於本人公眾號為訂閱號,沒有網頁授權獲取使用者基本資訊的介面,所以下面使用微信提供的測試賬號進行開發。

這裡寫圖片描述

進入之後的頁面

這裡寫圖片描述

往下拉,找到網頁服務-網頁授權獲取使用者資訊-修改

這裡寫圖片描述

點進去之後,填寫伺服器域名即可

這裡寫圖片描述

第二步 開發流程

1.使用者同意授權,獲取code
使用者點選授權連結(這裡用auth.html包裝一下),請求微信後臺api,微信後臺再回調到你指定的伺服器介面。
auth.html

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>微信測試獲取使用者資訊</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
  </head>
  <body>
  <script type="text/javascript">
        //頁面自動跳轉地址(非靜默授權連結) 引數appid為公眾號的id redirect_uri為微信回撥介面 state為可攜帶的引數(可選,這裡寫的是回撥介面處理完跳轉到指定頁面) 其餘引數不變
        window.location.href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=http://songhui.tunnel.qydev.com/micomo/inter/BackWet&response_type=code&scope=snsapi_userinfo&state=index.html#wechat_redirect";
  </script>
  </body>
</html>

2.第二步:通過code換取網頁授權access_token(該access_token和一般介面呼叫是使用的access_token 不同)和openid,再獲取使用者資訊
微信回撥介面程式碼
BackWet.java

package com.sh.inter;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;
import com.sh.util.Http;

public class BackWet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);

    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        String json1 = "";//獲取access_token
        String json2 = "";//獲取使用者資訊
        String state = request.getParameter("state");//跳轉頁面標識
        String code = request.getParameter("code");//通過code獲取access_token
        String httpurl = "https://api.weixin.qq.com/sns/oauth2/access_token";
        String param = "appid=APPID&secret=APPSECRET&code="+code+"&grant_type=authorization_code";

            //網頁授權獲取使用者資訊時用於獲取access_token以及openid的請求路徑: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code(最後一個引數不變)

        try {
            json1 = Http.methodGet(httpurl,param);//Http類會在後面貼出連結
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         JSONObject jsonToken = new JSONObject(json1);
         String access_token = jsonToken.getString("access_token");
         String openid = jsonToken.getString("openid");

         //通過access_token和openid請求獲取使用者資訊https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
           try {
                json2 = Http.methodGet("https://api.weixin.qq.com/sns/userinfo","access_token="+access_token+"&openid="+openid+"");
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
             JSONObject jsonUser = new JSONObject(json2);
             String nickname = jsonUser.getString("nickname");
             String headimgurl = jsonUser.getString("headimgurl");
             byte b[] = nickname.getBytes("UTF-8");
             nickname = new String(b, "UTF-8");

             request.getSession().setAttribute("nickname", nickname);
             request.getSession().setAttribute("headimgurl", headimgurl);
             response.sendRedirect("/micomo/"+state+"");//跳轉到指定頁面
             request.setCharacterEncoding("UTF-8");
    }

}

注意不同介面的url,以及網頁授權access_token與介面呼叫access_token的區別。