微信開發(fā)之微信網(wǎng)頁授權(quán)

微信網(wǎng)頁授權(quán)

所謂的微信網(wǎng)頁授權(quán)說白了就是 用戶微信客戶端內(nèi)訪問第三方網(wǎng)頁汛聚,公眾號可以根據(jù)網(wǎng)頁授權(quán)這個機制來獲取用戶的基本信息棍潘,然后進行相應(yīng)的邏輯處理。

官方文檔 : https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

準(zhǔn)備工作:

1 微信為我們提供了相應(yīng)的測試賬號

可以參考文檔 第二章 “微信開發(fā)之環(huán)境搭建”

或者直接看官方文檔 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

2 填寫自己的服務(wù)器url 用于接收微信返回事件xml數(shù)據(jù)。

在這里插入圖片描述

3 添加自己的 網(wǎng)頁授權(quán)回調(diào)域名

? 關(guān)于網(wǎng)頁授權(quán)回調(diào)域名的說明

1、在微信公眾號請求用戶網(wǎng)頁授權(quán)之前堤器,開發(fā)者需要先到公眾平臺官網(wǎng)中的“ 開發(fā) - 接口權(quán)限 - 網(wǎng)頁服務(wù) - 網(wǎng)頁帳號 - 網(wǎng)頁授權(quán)獲取用戶基本信息”的配置選項中,修改授權(quán)回調(diào)域名末贾。請注意闸溃,這里填寫的是域名(是一個字符串),而不是URL拱撵,因此請勿加 http:// 等協(xié)議頭辉川;

2、授權(quán)回調(diào)域名配置規(guī)范為全域名拴测,比如需要網(wǎng)頁授權(quán)的域名為:www.qq.com乓旗,配置以后此域名下面的頁面http://www.qq.com/music.htmlhttp://www.qq.com/login.html 都可以進行OAuth2.0鑒權(quán)集索。但http://pay.qq.com 屿愚、 http://music.qq.comhttp://qq.com無法進行OAuth2.0鑒權(quán)

3抄谐、如果公眾號登錄授權(quán)給了第三方開發(fā)者來進行管理渺鹦,則不必做任何設(shè)置,由第三方代替公眾號實現(xiàn)網(wǎng)頁授權(quán)即可

在這里插入圖片描述

配置回調(diào)域名 :

在這里插入圖片描述

點擊修改 填寫自己的回調(diào)域名蛹含,開頭不需要以 http:// 或者 https:// 開頭

在這里插入圖片描述

需要注意此處的access_token區(qū)別

關(guān)于網(wǎng)頁授權(quán)access_token和普通access_token的區(qū)別

1毅厚、微信網(wǎng)頁授權(quán)是通過OAuth2.0機制實現(xiàn)的,在用戶授權(quán)給公眾號后浦箱,公眾號可以獲取到一個網(wǎng)頁授權(quán)特有的接口調(diào)用憑證(網(wǎng)頁授權(quán)access_token)吸耿,通過網(wǎng)頁授權(quán)access_token可以進行授權(quán)后接口調(diào)用祠锣,如獲取用戶基本信息;

2咽安、其他微信接口伴网,需要通過基礎(chǔ)支持中的“獲取access_token”接口來獲取到的普通access_token調(diào)用。

關(guān)于網(wǎng)頁授權(quán)的兩種scope的區(qū)別說明

1妆棒、以snsapi_base為scope發(fā)起的網(wǎng)頁授權(quán)澡腾,是用來獲取進入頁面的用戶的openid的,并且是靜默授權(quán)并自動跳轉(zhuǎn)到回調(diào)頁的糕珊。用戶感知的就是直接進入了回調(diào)頁(往往是業(yè)務(wù)頁面)

2动分、以snsapi_userinfo為scope發(fā)起的網(wǎng)頁授權(quán),是用來獲取用戶的基本信息的红选。但這種授權(quán)需要用戶手動同意澜公,并且由于用戶同意過,所以無須關(guān)注喇肋,就可在授權(quán)后獲取該用戶的基本信息坟乾。

3、用戶管理類接口中的“獲取用戶基本信息接口”蝶防,是在用戶和公眾號產(chǎn)生消息交互或關(guān)注后事件推送后甚侣,才能根據(jù)用戶OpenID來獲取用戶基本信息。這個接口慧脱,包括其他微信接口渺绒,都是需要該用戶(即openid)關(guān)注了公眾號后,才能調(diào)用成功的菱鸥。

關(guān)于以上1,2 兩種scope機制對比

網(wǎng)頁授權(quán)方式 是否提示授權(quán) 獲取信息
snsapi_base 只能獲取openid
snsapi_userinfo 可獲取到更詳細(xì)的信息包括openid躏鱼,昵稱氮采,地址等等

snsapi_userinfo 會顯示下面授權(quán)頁面,snsapi_base是不會顯示的染苛!

img

第三條說明即是 :

? 用戶和公眾號產(chǎn)生消息交互或關(guān)注后事件推送后(xml數(shù)據(jù))鹊漠,可以根據(jù)xml數(shù)據(jù)中的用戶openid調(diào)用 “獲取用戶基本信息接口”獲取用戶詳細(xì)信息,但這個前提是用戶必須先關(guān)注公眾號茶行!

關(guān)于特殊場景下的靜默授權(quán)

1躯概、上面已經(jīng)提到,對于以snsapi_base為scope的網(wǎng)頁授權(quán)畔师,就靜默授權(quán)的娶靡,用戶無感知;

2看锉、對于已關(guān)注公眾號的用戶姿锭,如果用戶從公眾號的會話或者自定義菜單進入本公眾號的網(wǎng)頁授權(quán)頁塔鳍,即使是scope為snsapi_userinfo,也是靜默授權(quán)呻此,用戶無感知轮纫。

步驟主要分為四步:

第一步:用戶同意授權(quán),獲取code

在確保微信公眾賬號擁有授權(quán)作用域(scope參數(shù))的權(quán)限的前提下(服務(wù)號獲得高級接口后焚鲜,默認(rèn)擁有scope參數(shù)中的snsapi_base和snsapi_userinfo)掌唾,引導(dǎo)關(guān)注者打開如下頁面:

https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“該鏈接無法訪問”,請檢查參數(shù)是否填寫錯誤,是否擁有scope參數(shù)對應(yīng)的授權(quán)作用域權(quán)限序目。

尤其注意:由于授權(quán)操作安全等級較高薪前,所以在發(fā)起授權(quán)請求時,微信會對授權(quán)鏈接做正則強匹配校驗情连,如果鏈接的參數(shù)順序不對,授權(quán)頁面將無法正常訪問

參考鏈接(請在微信客戶端中打開此鏈接體驗):

scope為snsapi_base

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx520c15f417810387&redirect_uri=https%3A%2F%2Fchong.qq.com%2Fphp%2Findex.php%3Fd%3D%26c%3DwxAdapter%26m%3DmobileDeal%26showwxpaytitle%3D1%26vb2ctag%3D4_2030_5_1194_60&response_type=code&scope=snsapi_base&state=123#wechat_redirect

scope為snsapi_userinfo

https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxf0e81c3bee622d60&redirect_uri=http%3A%2F%2Fnba.bluewebgame.com%2Foauth_response.php&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect

參數(shù)說明

參數(shù) 是否必須 說明
appid 公眾號的唯一標(biāo)識
redirect_uri 授權(quán)后重定向的回調(diào)鏈接地址览效, 請使用 urlEncode 對鏈接進行處理
response_type 返回類型却舀,請?zhí)顚慶ode
scope 應(yīng)用授權(quán)作用域,snsapi_base (不彈出授權(quán)頁面锤灿,直接跳轉(zhuǎn)挽拔,只能獲取用戶openid),snsapi_userinfo (彈出授權(quán)頁面但校,可通過openid拿到昵稱螃诅、性別、所在地状囱。并且术裸, 即使在未關(guān)注的情況下,只要用戶授權(quán)亭枷,也能獲取其信息 )
state 重定向后會帶上state參數(shù)袭艺,開發(fā)者可以填寫a-zA-Z0-9的參數(shù)值,最多128字節(jié)
#wechat_redirect 無論直接打開還是做頁面302重定向時候叨粘,必須帶此參數(shù)

尤其注意:跳轉(zhuǎn)回調(diào)redirect_uri猾编,應(yīng)當(dāng)使用https鏈接來確保授權(quán)code的安全性。

redirect_uri 的url 需要我們自己來定義升敲。

如點擊url進入 第三方網(wǎng)頁url

    //授權(quán)后跳轉(zhuǎn)的url地址
    String redirect_uri ="http://www.udeam.com" + "/getUserInfo";
    String 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è)置自己的appid 和 授權(quán)機制
    url = url.replace("APPID","xxxxxxxxxxxxxxx").replace("SCOPE","snsapi_userinfo");

授權(quán)后跳轉(zhuǎn)的url地址 controller

/**
 * 網(wǎng)頁授權(quán)獲取用戶信息  用戶同意授權(quán) , 獲取code
 * @param code
 * @return 頁面
 */
@GetMapping("getUserInfo")
public String getUserInfo(String code){
    logger.info("code = " + code);
    //獲取用戶信息
    String userAuthorzation = UserService.userAuthorzation(code);
    //返回數(shù)據(jù)錯誤
    if (userAuthorzation.equals("error")){ return "500";}

    return "sucess";
}

第二步:通過code換取網(wǎng)頁授權(quán)access_token

首先請注意答倡,這里通過code換取的是一個特殊的網(wǎng)頁授權(quán)access_token,與基礎(chǔ)支持中的access_token(該access_token用于調(diào)用其他接口)不同。公眾號可通過下述接口來獲取網(wǎng)頁授權(quán)access_token驴党。如果網(wǎng)頁授權(quán)的作用域為snsapi_base瘪撇,則本步驟中獲取到網(wǎng)頁授權(quán)access_token的同時,也獲取到了openid,snsapi_base式的網(wǎng)頁授權(quán)流程即到此為止设江。

尤其注意:由于公眾號的secret和獲取到的access_token安全級別都非常高锦茁,必須只保存在服務(wù)器,不允許傳給客戶端叉存。后續(xù)刷新access_token码俩、通過access_token獲取用戶信息等步驟,也必須從服務(wù)器發(fā)起歼捏。

請求方法

獲取code后稿存,請求以下鏈接獲取access_token:

  https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

參數(shù)說明

參數(shù) 是否必須 說明
appid 公眾號的唯一標(biāo)識
secret 公眾號的appsecret
code 填寫第一步獲取的code參數(shù)
grant_type 填寫為authorization_code

返回說明

正確時返回的JSON數(shù)據(jù)包如下:

{
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE" 
 }
參數(shù) 描述
access_token 網(wǎng)頁授權(quán)接口調(diào)用憑證,注意:此access_token與基礎(chǔ)支持的access_token不同
expires_in access_token接口調(diào)用憑證超時時間,單位(秒)
refresh_token 用戶刷新access_token
openid 用戶唯一標(biāo)識瞳秽,請注意瓣履,在未關(guān)注公眾號時,用戶訪問公眾號的網(wǎng)頁练俐,也會產(chǎn)生一個用戶和公眾號唯一的OpenID
scope 用戶授權(quán)的作用域袖迎,使用逗號(,)分隔

錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為Code無效錯誤):

{"errcode":40029,"errmsg":"invalid code"}

第三步:刷新access_token(如果需要)

由于access_token擁有較短的有效期,當(dāng)access_token超時后腺晾,可以使用refresh_token進行刷新燕锥,refresh_token有效期為30天,當(dāng)refresh_token失效之后悯蝉,需要用戶重新授權(quán)归形。

請求方法

獲取第二步的refresh_token后,請求以下鏈接獲取access_token:
https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
參數(shù) 是否必須 說明
appid 公眾號的唯一標(biāo)識
grant_type 填寫為refresh_token
refresh_token 填寫通過access_token獲取到的refresh_token參數(shù)

返回說明

正確時返回的JSON數(shù)據(jù)包如下:

{ 
    "access_token":"ACCESS_TOKEN",
    "expires_in":7200,
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID",
    "scope":"SCOPE" 
}
參數(shù) 描述
access_token 網(wǎng)頁授權(quán)接口調(diào)用憑證,注意:此access_token與基礎(chǔ)支持的access_token不同
expires_in access_token接口調(diào)用憑證超時時間鼻由,單位(秒)
refresh_token 用戶刷新access_token
openid 用戶唯一標(biāo)識
scope 用戶授權(quán)的作用域暇榴,使用逗號(,)分隔

錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為code無效錯誤):

{"errcode":40029,"errmsg":"invalid code"}

第四步:拉取用戶信息(需scope為 snsapi_userinfo)

” 拉取用戶信息 “ 前提 是 網(wǎng)頁授權(quán)作用域為snsapi_userinfo,則此時開發(fā)者可以通過access_token和openid拉取用戶信息了蕉世。

請求方法

http:GET(請使用https協(xié)議) https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN

參數(shù)說明

參數(shù) 描述
access_token 網(wǎng)頁授權(quán)接口調(diào)用憑證,注意:此access_token與基礎(chǔ)支持的access_token不同
openid 用戶的唯一標(biāo)識
lang 返回國家地區(qū)語言版本蔼紧,zh_CN 簡體,zh_TW 繁體讨彼,en 英語

返回數(shù)據(jù)說明

正確時返回的JSON數(shù)據(jù)包如下:

{   
    "openid":" OPENID",
    " nickname": NICKNAME,
    "sex":"1",
    "province":"PROVINCE"
    "city":"CITY",
    "country":"COUNTRY",
    "headimgurl":       "http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/46",
    "privilege":[ "PRIVILEGE1" "PRIVILEGE2"     ],
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
參數(shù) 描述
openid 用戶的唯一標(biāo)識
nickname 用戶昵稱
sex 用戶的性別歉井,值為1時是男性,值為2時是女性哈误,值為0時是未知
province 用戶個人資料填寫的省份
city 普通用戶個人資料填寫的城市
country 國家,如中國為CN
headimgurl 用戶頭像躏嚎,最后一個數(shù)值代表正方形頭像大忻圩浴(有0、46卢佣、64重荠、96、132數(shù)值可選虚茶,0代表640*640正方形頭像)戈鲁,用戶沒有頭像時該項為空仇参。若用戶更換頭像,原有頭像URL將失效婆殿。
privilege 用戶特權(quán)信息诈乒,json 數(shù)組,如微信沃卡用戶為(chinaunicom)
unionid 只有在用戶將公眾號綁定到微信開放平臺帳號后婆芦,才會出現(xiàn)該字段怕磨。

錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為openid無效):

{"errcode":40003,"errmsg":" invalid openid "}

通過code 獲取 網(wǎng)頁access_token 和 用戶信息 代碼實現(xiàn)

/**
 * 網(wǎng)頁授權(quán)獲取用戶信息  用戶同意授權(quán) , 獲取code
 * @param args
 */
public static String userAuthorzation(String code){
    //2 通過code換取網(wǎng)頁授權(quán)access_token
    String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    url=url.replace("APPID","xxxxxx").replace("SECRET","xxxxxxxxx").replace("CODE",code);
    String result = HttpUtil.sendHttpByGet(url);//發(fā)送請求
    logger.info("通過code換取網(wǎng)頁授權(quán)access_token 的 result = " + result);

    /**
     * 正確時返回的JSON數(shù)據(jù)包如下:
     * { "access_token":"ACCESS_TOKEN",
     * "expires_in":7200,
     * "refresh_token":"REFRESH_TOKEN",
     * "openid":"OPENID",
     * "scope":"SCOPE" }
     * 錯誤時微信會返回JSON數(shù)據(jù)包如下(示例為Code無效錯誤):
     * {"errcode":40029,"errmsg":"invalid code"}
     */
    JSONObject jsonObject = JSONObject.parseObject(result);
    String access_token = jsonObject.getString("access_token");
    String openid = jsonObject.getString("openid");

    //返回的數(shù)據(jù)是后出錯
    if(jsonObject!=null && jsonObject.toJSONString().contains("errcode")){
        logger.info("通過code換取網(wǎng)頁授權(quán)access_token 返回數(shù)據(jù)時出錯!");
        return "error";
    }
    //第三步:刷新access_token(如果需要)
    //第四步:拉取用戶信息(需scope為 snsapi_userinfo)
    String userMsg = getUserMsg(openid);
    jsonObject = JSONObject.parseObject(userMsg);
    if(jsonObject!=null && jsonObject.toJSONString().contains("access_token")) {
        logger.info("拉取用戶信息 消约! " + jsonObject.toJSONString());
        return jsonObject.toJSONString();
    } 

    logger.info("拉取用戶信息失敵辍!  " + result);
    
    return "error";
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末或粮,一起剝皮案震驚了整個濱河市导饲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氯材,老刑警劉巖渣锦,帶你破解...
    沈念sama閱讀 222,378評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異浓体,居然都是意外死亡泡挺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,970評論 3 399
  • 文/潘曉璐 我一進店門命浴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來娄猫,“玉大人,你說我怎么就攤上這事生闲∠蹦纾” “怎么了?”我有些...
    開封第一講書人閱讀 168,983評論 0 362
  • 文/不壞的土叔 我叫張陵碍讯,是天一觀的道長悬蔽。 經(jīng)常有香客問我,道長捉兴,這世上最難降的妖魔是什么蝎困? 我笑而不...
    開封第一講書人閱讀 59,938評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮倍啥,結(jié)果婚禮上禾乘,老公的妹妹穿的比我還像新娘。我一直安慰自己虽缕,他們只是感情好始藕,可當(dāng)我...
    茶點故事閱讀 68,955評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般伍派。 火紅的嫁衣襯著肌膚如雪江耀。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,549評論 1 312
  • 那天诉植,我揣著相機與錄音祥国,去河邊找鬼。 笑死倍踪,一個胖子當(dāng)著我的面吹牛系宫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播建车,決...
    沈念sama閱讀 41,063評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼扩借,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了缤至?” 一聲冷哼從身側(cè)響起潮罪,我...
    開封第一講書人閱讀 39,991評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎领斥,沒想到半個月后嫉到,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,522評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡月洛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,604評論 3 342
  • 正文 我和宋清朗相戀三年何恶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嚼黔。...
    茶點故事閱讀 40,742評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡细层,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出唬涧,到底是詐尸還是另有隱情疫赎,我是刑警寧澤,帶...
    沈念sama閱讀 36,413評論 5 351
  • 正文 年R本政府宣布碎节,位于F島的核電站捧搞,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏狮荔。R本人自食惡果不足惜胎撇,卻給世界環(huán)境...
    茶點故事閱讀 42,094評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望殖氏。 院中可真熱鬧创坞,春花似錦、人聲如沸受葛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,572評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽总滩。三九已至纲堵,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間闰渔,已是汗流浹背席函。 一陣腳步聲響...
    開封第一講書人閱讀 33,671評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留冈涧,地道東北人茂附。 一個月前我還...
    沈念sama閱讀 49,159評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像督弓,于是被迫代替她去往敵國和親营曼。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,747評論 2 361

推薦閱讀更多精彩內(nèi)容