微信公衆號開發之受權獲取用戶信息

微信開發交流羣:148540125html

系列文章參考地址 極速開發微信公衆號
歡迎留言、轉發、打賞git

項目源碼參考地址 點我點我--歡迎Start數據庫

前幾篇文章已講完如何導入項目,如何啓動配置項目,如何成爲開發者,重源碼分析消息是如何交互、如何自定義菜單(若是以上不是很清楚能夠看這裏 極速開發微信公衆號。這篇文章就來聊聊受權獲取用戶信息json

1、什麼是OAuth2.0

這裏整理了一篇文章 理解OAuth2.0api

2、微信公衆平臺OAuth2.0受權詳細步驟

  1. 用戶關注微信公衆帳號(如今也能夠不關注)。
  2. 微信公衆帳號提供用戶請求受權頁面URL。
  3. 用戶點擊受權頁面URL,將向服務器發起請求
  4. 服務器詢問用戶是否贊成受權給微信公衆帳號(scope爲snsapi_base時無此步驟)
  5. 用戶贊成(scope爲snsapi_base時無此步驟,不彈出受權頁面,直接跳轉,只能獲取用戶openid)
  6. 服務器將code參數經過回調傳給微信公衆帳號
  7. 微信公衆帳號得到code參數
  8. 微信公衆帳號經過code參數向服務器請求Access Token
  9. 服務器返回Access Token和OpenID給微信公衆帳號
  10. 微信公衆帳號經過Access Token向服務器請求用戶信息(scope爲snsapi_base時無此步驟)
  11. 服務器將用戶信息回送給微信公衆帳號(scope爲snsapi_base時無此步驟)

3、配置受權回調頁面域名

沙盒號(測試號)回調地址支持域名和ip,正式公衆號回調地址只支持域名而且域名需使用字母、數字及「-」的組合,須經過ICP備案的驗證,不支持端口號及短鏈。服務器

測試號:找到 網頁受權獲取用戶基本信息>點擊修改>設置域名
服務號:找到 開發>接口權限>網頁受權獲取用戶基本信息>>點擊修改>設置域名微信

詳細介紹參考官方文檔微信開發

4、用戶受權並獲取code ,使用code換取access_token 並使用access_token獲取用戶信息

受權訪問的URL:app

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

具體封裝實現能夠查看com.jfinal.weixin.sdk.api.SnsAccessTokenApi.getAuthorizeURL(....) 方法

以前博客使用Servlet 也寫了一個簡單的受權參考地址

5、使用封裝的接口實現受權獲取用戶信息

封裝以後使用就很是的簡單,SnsAccessTokenApi.getAuthorizeURL(....)

  • 第一個參數爲appId
  • 第二個參數爲受權後回調的地址http://域名/oauth
  • 第三個參數爲state 重定向後會帶上state參數,開發者能夠填寫a-zA-Z0-9的參數值,最多128字節 第四個參數 應用受權做用域,簡單講是否彈出受權頁面 。 true 爲不彈出受權頁面

應用受權做用域,snsapi_base (不彈出受權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出受權頁面,可經過openid拿到暱稱、性別、所在地。而且,即便在未關注的狀況下,只要用戶受權,也能獲取其信息

具體實現代碼以下

//跳轉到受權頁面
  public void toOauth(){
    String calbackUrl=PropKit.get("domain")+"/oauth";
    String url=SnsAccessTokenApi.getAuthorizeURL(PropKit.get("appId"), calbackUrl, "111",false);
    redirect(url);
  }

oauth Controller 具體實現步驟以下:

  • 當用戶贊成受權,獲取code以及state
  • 若是code不爲null,就能夠經過code換取網頁受權access_token
{ 
 "access_token":"ACCESS_TOKEN",    
 "expires_in":7200,    
 "refresh_token":"REFRESH_TOKEN",    
 "openid":"OPENID",    
 "scope":"SCOPE" 
}
  • 拉取用戶信息(需scope爲 snsapi_userinfo)
{    
 "openid":" OPENID",  
 " nickname": NICKNAME,   
 "sex":"1",   
 "province":"PROVINCE"   
 "city":"CITY",   
 "country":"COUNTRY",    
 "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ
4eMsv84eavHiaiceqxibJxCfHe/46",  
"privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],    
 "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" 
}
  • 獲取用戶信息以後能夠根據上面的state跳轉到不一樣的頁面

具體實現代碼以下

public class WeiXinOauthController extends ApiController{
  static Log log = Log.getLog(WeiXinOauthController.class);
  /**
   * 若是要支持多公衆帳號,只須要在此返回各個公衆號對應的  ApiConfig 對象便可
   * 能夠經過在請求 url 中掛參數來動態從數據庫中獲取 ApiConfig 屬性值
   */
  public ApiConfig getApiConfig() {
    ApiConfig ac = new ApiConfig();
    
    // 配置微信 API 相關常量
    ac.setToken(PropKit.get("token"));
    ac.setAppId(PropKit.get("appId"));
    ac.setAppSecret(PropKit.get("appSecret"));
    
    /**
     *  是否對消息進行加密,對應於微信平臺的消息加解密方式:
     *  1:true進行加密且必須配置 encodingAesKey
     *  2:false採用明文模式,同時也支持混合模式
     */
    ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
    ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
    return ac;
  }
  
  public void index() {
    int  subscribe=0;
    //用戶贊成受權,獲取code
    String code=getPara("code");
    String state=getPara("state");
    if (code!=null) {
      String appId=ApiConfigKit.getApiConfig().getAppId();
      String secret=ApiConfigKit.getApiConfig().getAppSecret();
      //經過code換取網頁受權access_token
      SnsAccessToken snsAccessToken=SnsAccessTokenApi.getSnsAccessToken(appId,secret,code);
//      String json=snsAccessToken.getJson();
      String token=snsAccessToken.getAccessToken();
      String openId=snsAccessToken.getOpenid();
      //拉取用戶信息(需scope爲 snsapi_userinfo)
      ApiResult apiResult=SnsApi.getUserInfo(token, openId);
      
      log.warn("getUserInfo:"+apiResult.getJson());
      if (apiResult.isSucceed()) {
        JSONObject jsonObject=JSON.parseObject(apiResult.getJson());
        String nickName=jsonObject.getString("nickname");
        //用戶的性別,值爲1時是男性,值爲2時是女性,值爲0時是未知
        int sex=jsonObject.getIntValue("sex");
        String city=jsonObject.getString("city");//城市
        String province=jsonObject.getString("province");//省份
        String country=jsonObject.getString("country");//國家
        String headimgurl=jsonObject.getString("headimgurl");
        String unionid=jsonObject.getString("unionid");
        //獲取用戶信息判斷是否關注
        ApiResult userInfo = UserApi.getUserInfo(openId);
        log.warn(JsonKit.toJson("is subsribe>>"+userInfo));
        if (userInfo.isSucceed()) {
          String userStr = userInfo.toString();
          subscribe=JSON.parseObject(userStr).getIntValue("subscribe");
        }
        
        Users.me.save(openId, WeiXinUtils.filterWeixinEmoji(nickName), unionid, headimgurl, country, city, province, sex);
      }
      
      setSessionAttr("openId", openId);
      if (subscribe==0) {
        redirect(PropKit.get("subscribe_rul"));
      }else {
        //根據state 跳轉到不一樣的頁面
        if (state.equals("2222")) {
          redirect("http://www.cnblogs.com/zyw-205520/");
        }else {
          redirect("/login");
        }
      }
    }else {
      renderText("code is  null");
    }
  }
}

以上是受權獲取用戶信息的全過程。

歡迎留言、轉發、打賞
項目源碼參考地址 點我點我--歡迎Start

相關文章
相關標籤/搜索