微信網(wǎng)頁(yè)授權(quán)并獲取用戶(hù)信息的方法
介紹
在很多微信H5應(yīng)用里,當(dāng)用戶(hù)訪問(wèn)第三方應(yīng)用時(shí)就需要進(jìn)行微信網(wǎng)頁(yè)授權(quán),并且很多涉及安全的操作我們必須要先獲取用戶(hù)信息才能繼續(xù),本文章簡(jiǎn)單介紹了微信授權(quán)流程,并通過(guò)申請(qǐng)微信測(cè)試賬號(hào)來(lái)模擬網(wǎng)頁(yè)授權(quán),用戶(hù)在授權(quán)頁(yè)點(diǎn)擊確定登錄后獲取用戶(hù)信息并顯示在前端頁(yè)面,最后效果如下圖
工具及開(kāi)發(fā)準(zhǔn)備
1. 微信開(kāi)發(fā)者工具及微信測(cè)試號(hào)
因?yàn)槭俏⑿攀跈?quán),所以必須要在微信環(huán)境下使用,首先我們要在這里安裝微信開(kāi)發(fā)者工具,因?yàn)槲覀儧](méi)有自己的應(yīng)用,所以還需要在微信公眾平臺(tái)申請(qǐng)一個(gè)接口測(cè)試號(hào),這個(gè)接口測(cè)試號(hào)就相當(dāng)于我們的第三方應(yīng)用。
2. 參數(shù)設(shè)置
登陸測(cè)試號(hào)后可以查看到自己的appId和appsecret信息,將體驗(yàn)接口權(quán)限表里的網(wǎng)頁(yè)服務(wù)的網(wǎng)頁(yè)授權(quán)獲取用戶(hù)基本信息修改為127.0.0.1:8800,該地址就是用戶(hù)確認(rèn)授權(quán)后回調(diào)的地址即我們應(yīng)用的后臺(tái)處理地址,如下圖
最后拿出自己微信掃碼關(guān)注該測(cè)試號(hào)即可,如下圖所示
微信授權(quán)流程介紹
具體流程及詳細(xì)介紹大家可以到官網(wǎng)微信公眾平臺(tái)技術(shù)文檔查看,大致分為四步:
1. 引導(dǎo)用戶(hù)進(jìn)入授權(quán)頁(yè)面同意授權(quán),此時(shí)會(huì)調(diào)用微信api獲取code
2. 授權(quán)通過(guò)后會(huì)帶上code參數(shù)請(qǐng)求回調(diào)地址
3. 后臺(tái)獲取code,再次調(diào)用微信接口換取網(wǎng)頁(yè)授權(quán)access_token和openid
4. 通過(guò)網(wǎng)頁(yè)授權(quán)access_token和openid獲取用戶(hù)基本信息(如果有unionid還會(huì)獲取到unionid參數(shù))
正式開(kāi)始
詳細(xì)代碼可以在github上下載,地址https://github.com/wangfengyuan/wxAuthorize
1. 原始代碼
let express = require("express");const https = require('https'); let app = express(); //appIDlet appID = `wxec6fa9e9bc03d885`; //appsecretlet appSerect = `4c8a0d14cff08959b4e17334cabf9cf0`; //點(diǎn)擊授權(quán)后重定向url地址 let redirectUrl = `/getUserInfo`; let host = `http://127.0.0.1:3000`; //微信授權(quán)api,接口返回code,點(diǎn)擊授權(quán)后跳轉(zhuǎn)到重定向地址并帶上code參數(shù) let authorizeUrl = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appID}&redirect_uri=` + `${host}${redirectUrl}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect` app.get("/login", function(req, res) { res.sendFile(path.resolve(__dirname,'login.html')); }); app.get("/auth", function(req, res) { res.writeHead(302, { 'Location': authorizeUrl }); res.end(); }); app.get("/getUserInfo", function(req, res) { let code = req.query.code; let getaccess = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=` + `${appID}&secret=${appSerect}&code=$[code]&grant_type=authorization_code`; //通過(guò)拿到的code和appID、app_serect獲取access_token和open_id https.get(getaccess, (resText) => { var ddd = ""; resText.on('data', (d) => { ddd += d; }); resText.on('end', () => { // console.log(ddd); var obj = JSON.parse(ddd); var access_token = obj.access_token; var open_id = obj.openid; //通過(guò)上一步獲取的access_token和open_id獲取userInfo即用戶(hù)信息 let getUserUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${open_id}⟨=zh_CN`; https.get(getUserUrl, (resText) => { user = ""; resText.on('data', (d) => { user += d; }); resText.on('end', () => { console.log(user); var userobj = JSON.parse(user); res.send(userobj); console.log(userobj); }); }) }); }).on('error', (e) => { console.error(e); }); app.listen(3000);
具體使用時(shí)要將appID和appSerect換成你對(duì)應(yīng)的參數(shù)即可,因?yàn)槲覀兊恼?qǐng)求是要按一定順序的,但是node發(fā)送請(qǐng)求是異步的,所以我們的請(qǐng)求嵌套了三層,代碼很難看,所以這里可以采用ES6的async和await解決異步回調(diào)地獄。
2. 使用ES6的async和await的改進(jìn)代碼
async function wxAuth(req, res) { //解析querystring獲取URL中的code值 let code = req.query.code; //通過(guò)拿到的code和appID、app_serect獲取返回信息 let resObj = await getAccessToken(code); //解析得到access_token和open_id let access_token = resObj.access_token; let open_id = resObj.openid; //通過(guò)上一步獲取的access_token和open_id獲取userInfo即用戶(hù)信息 let userObj = await getUserInfo(access_token, open_id); console.log(userObj); res.render(path.resolve(__dirname,'userInfo.ejs'), {userObj: userObj}); // res.send(userObj);} //通過(guò)拿到的code和appID、app_serect獲取access_token和open_id function getAccessToken(code) { return new Promise( (resolve, reject) => { let getAccessUrl = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=` + `${appID}&secret=${appSerect}&code=$[code]&grant_type=authorization_code`; https.get(getAccessUrl, (res) => { var resText = ""; res.on('data', (d) => { resText += d; }); res.on('end', () => { var resObj = JSON.parse(resText); resolve(resObj); }); }).on('error', (e) => { console.error(e); }); }); } //通過(guò)上一步獲取的access_token和open_id獲取userInfo即用戶(hù)信息 function getUserInfo(access_token, open_id) { return new Promise( (resolve, reject) => { let getUserUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${open_id}⟨=zh_CN`; https.get(getUserUrl, (res) => { var resText = ""; res.on('data', (d) => { resText += d; }); res.on('end', () => { var userObj = JSON.parse(resText); resolve(userObj); }); }).on('error', (e) => { console.error(e); }); })}
修改后代碼流程清晰了很多,最后點(diǎn)擊確認(rèn)登陸后將獲取到的userObj通過(guò)ejs模板渲染在前端頁(yè)面,就能看到文章最開(kāi)始展現(xiàn)的效果圖。
寫(xiě)在最后
我前端剛?cè)腴T(mén)沒(méi)多久,最近在公司實(shí)習(xí),受到身邊同事影響,所以也開(kāi)始寫(xiě)文章來(lái)記錄自己的學(xué)習(xí)心得,這是我第一次寫(xiě)文章,所以可能寫(xiě)的不太好,大家對(duì)文章和代碼有什么建議歡迎提出來(lái)一起交流,謝謝!也希望大家多多支持腳本之家。
相關(guān)文章
es6中使用map簡(jiǎn)化復(fù)雜條件判斷操作實(shí)例詳解
這篇文章主要介紹了es6中使用map簡(jiǎn)化復(fù)雜條件判斷操作,結(jié)合實(shí)例形式詳細(xì)分析了傳統(tǒng)方法與map簡(jiǎn)化復(fù)雜條件判斷的相關(guān)操作技巧,需要的朋友可以參考下2020-02-02Javascript將數(shù)字轉(zhuǎn)化成為貨幣格式字符串
這篇文章主要介紹Javascript將數(shù)字轉(zhuǎn)化成為貨幣格式字符串的方法,通俗易懂,需要的朋友可以參考下。2016-06-06比JSON.stringify快兩倍的fast-json-stringify性能對(duì)比分析
這篇文章主要為大家介紹了比JSON.stringify快兩倍的fast-json-stringify性能對(duì)比分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12淺談js對(duì)象的創(chuàng)建和對(duì)6種繼承模式的理解和遐想
下面小編就為大家?guī)?lái)一篇淺談js對(duì)象的創(chuàng)建和對(duì)6種繼承模式的理解和遐想。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10動(dòng)態(tài)加載圖片路徑 保持JavaScript控件的相對(duì)獨(dú)立性
根據(jù)新界面的要求,需要一部分圖片來(lái)增強(qiáng)日期控件的美觀性??紤]到既要實(shí)現(xiàn)加載圖表的目標(biāo),又要保持控件的獨(dú)立性以便將來(lái)的移植。2010-09-09javascript的23種設(shè)計(jì)模式示例總結(jié)大全
這篇文章主要為大家介紹了javascript的23種設(shè)計(jì)模式的總結(jié)大全,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06