微信公眾號(hào)開發(fā)之授權(quán)獲取用戶信息

微信開發(fā)交流群:148540125

系列文章參考地址 極速開發(fā)微信公眾號(hào)
歡迎留言、轉(zhuǎn)發(fā)、打賞

項(xiàng)目源碼參考地址 點(diǎn)我點(diǎn)我--歡迎Start

前幾篇文章已講完如何導(dǎo)入項(xiàng)目,如何啟動(dòng)配置項(xiàng)目,如何成為開發(fā)者,重源碼分析消息是如何交互、如何自定義菜單(如果以上不是很清楚可以看這里 極速開發(fā)微信公眾號(hào)。這篇文章就來(lái)聊聊授權(quán)獲取用戶信息

一、什么是OAuth2.0

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

二、微信公眾平臺(tái)OAuth2.0授權(quán)詳細(xì)步驟

  1. 用戶關(guān)注微信公眾賬號(hào)(現(xiàn)在也可以不關(guān)注)。
  2. 微信公眾賬號(hào)提供用戶請(qǐng)求授權(quán)頁(yè)面URL。
  3. 用戶點(diǎn)擊授權(quán)頁(yè)面URL,將向服務(wù)器發(fā)起請(qǐng)求
  4. 服務(wù)器詢問用戶是否同意授權(quán)給微信公眾賬號(hào)(scope為snsapi_base時(shí)無(wú)此步驟)
  5. 用戶同意(scope為snsapi_base時(shí)無(wú)此步驟,不彈出授權(quán)頁(yè)面,直接跳轉(zhuǎn),只能獲取用戶openid)
  6. 服務(wù)器將code參數(shù)通過回調(diào)傳給微信公眾賬號(hào)
  7. 微信公眾賬號(hào)獲得code參數(shù)
  8. 微信公眾賬號(hào)通過code參數(shù)向服務(wù)器請(qǐng)求Access Token
  9. 服務(wù)器返回Access Token和OpenID給微信公眾賬號(hào)
  10. 微信公眾賬號(hào)通過Access Token向服務(wù)器請(qǐng)求用戶信息(scope為snsapi_base時(shí)無(wú)此步驟)
  11. 服務(wù)器將用戶信息回送給微信公眾賬號(hào)(scope為snsapi_base時(shí)無(wú)此步驟)

三、配置授權(quán)回調(diào)頁(yè)面域名

沙盒號(hào)(測(cè)試號(hào))回調(diào)地址支持域名和ip,正式公眾號(hào)回調(diào)地址只支持域名并且域名需使用字母、數(shù)字及“-”的組合,須通過ICP備案的驗(yàn)證,不支持端口號(hào)及短鏈。

測(cè)試號(hào):找到 網(wǎng)頁(yè)授權(quán)獲取用戶基本信息>點(diǎn)擊修改>設(shè)置域名
服務(wù)號(hào):找到 開發(fā)>接口權(quán)限>網(wǎng)頁(yè)授權(quán)獲取用戶基本信息>>點(diǎn)擊修改>設(shè)置域名

詳細(xì)介紹參考官方文檔

javen_config.txt配置文件中配置授權(quán)域名

四、用戶授權(quán)并獲取code ,使用code換取access_token 并使用access_token獲取用戶信息

授權(quán)訪問的URL:

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

具體封裝實(shí)現(xiàn)可以查看com.jfinal.weixin.sdk.api.SnsAccessTokenApi.getAuthorizeURL(....) 方法

之前博客使用Servlet 也寫了一個(gè)簡(jiǎn)單的授權(quán)參考地址

五、使用封裝的接口實(shí)現(xiàn)授權(quán)獲取用戶信息

封裝之后使用就非常的簡(jiǎn)單,SnsAccessTokenApi.getAuthorizeURL(....)

  • 第一個(gè)參數(shù)為appId
  • 第二個(gè)參數(shù)為授權(quán)后回調(diào)的地址http://域名/oauth
  • 第三個(gè)參數(shù)為state 重定向后會(huì)帶上state參數(shù),開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值,最多128字節(jié) 第四個(gè)參數(shù) 應(yīng)用授權(quán)作用域,簡(jiǎn)單講是否彈出授權(quán)頁(yè)面 。 true 為不彈出授權(quán)頁(yè)面

應(yīng)用授權(quán)作用域,snsapi_base (不彈出授權(quán)頁(yè)面,直接跳轉(zhuǎn),只能獲取用戶openid),snsapi_userinfo (彈出授權(quán)頁(yè)面,可通過openid拿到昵稱、性別、所在地。并且,即使在未關(guān)注的情況下,只要用戶授權(quán),也能獲取其信息

具體實(shí)現(xiàn)代碼如下

//跳轉(zhuǎn)到授權(quán)頁(yè)面
  public void toOauth(){
    String calbackUrl=PropKit.get("domain")+"/oauth";
    String url=SnsAccessTokenApi.getAuthorizeURL(PropKit.get("appId"), calbackUrl, "111",false);
    redirect(url);
  }

oauth Controller 具體實(shí)現(xiàn)步驟如下:

  • 當(dāng)用戶同意授權(quán),獲取code以及state
  • 如果code不為null,就可以通過code換取網(wǎng)頁(yè)授權(quán)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" 
} 
  • 獲取用戶信息之后可以根據(jù)上面的state跳轉(zhuǎn)到不同的頁(yè)面

具體實(shí)現(xiàn)代碼如下

public class WeiXinOauthController extends ApiController{
  static Log log = Log.getLog(WeiXinOauthController.class);
  /**
   * 如果要支持多公眾賬號(hào),只需要在此返回各個(gè)公眾號(hào)對(duì)應(yīng)的  ApiConfig 對(duì)象即可
   * 可以通過在請(qǐng)求 url 中掛參數(shù)來(lái)動(dòng)態(tài)從數(shù)據(jù)庫(kù)中獲取 ApiConfig 屬性值
   */
  public ApiConfig getApiConfig() {
    ApiConfig ac = new ApiConfig();
    
    // 配置微信 API 相關(guān)常量
    ac.setToken(PropKit.get("token"));
    ac.setAppId(PropKit.get("appId"));
    ac.setAppSecret(PropKit.get("appSecret"));
    
    /**
     *  是否對(duì)消息進(jìn)行加密,對(duì)應(yīng)于微信平臺(tái)的消息加解密方式:
     *  1:true進(jìn)行加密且必須配置 encodingAesKey
     *  2:false采用明文模式,同時(shí)也支持混合模式
     */
    ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
    ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));
    return ac;
  }
  
  public void index() {
    int  subscribe=0;
    //用戶同意授權(quán),獲取code
    String code=getPara("code");
    String state=getPara("state");
    if (code!=null) {
      String appId=ApiConfigKit.getApiConfig().getAppId();
      String secret=ApiConfigKit.getApiConfig().getAppSecret();
      //通過code換取網(wǎng)頁(yè)授權(quán)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時(shí)是男性,值為2時(shí)是女性,值為0時(shí)是未知
        int sex=jsonObject.getIntValue("sex");
        String city=jsonObject.getString("city");//城市
        String province=jsonObject.getString("province");//省份
        String country=jsonObject.getString("country");//國(guó)家
        String headimgurl=jsonObject.getString("headimgurl");
        String unionid=jsonObject.getString("unionid");
        //獲取用戶信息判斷是否關(guān)注
        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 {
        //根據(jù)state 跳轉(zhuǎn)到不同的頁(yè)面
        if (state.equals("2222")) {
          redirect("http://www.cnblogs.com/zyw-205520/");
        }else {
          redirect("/login");
        }
      }
    }else {
      renderText("code is  null");
    }
  }
}

以上是授權(quán)獲取用戶信息的全過程。

歡迎留言、轉(zhuǎn)發(fā)、打賞
項(xiàng)目源碼參考地址 點(diǎn)我點(diǎn)我--歡迎Start

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容