微信網頁受權並獲取用戶信息

微信網頁受權並獲取用戶信息

介紹

在不少微信H5應用裏,當用戶訪問第三方應用時就須要進行微信網頁受權,而且不少涉及安全的操做咱們必需要先獲取用戶信息才能繼續,本文章簡單介紹了微信受權流程,並經過申請微信測試帳號來模擬網頁受權,用戶在受權頁點擊肯定登陸後獲取用戶信息並顯示在前端頁面,最後效果以下圖html

圖片描述

工具及開發準備

1. 微信開發者工具及微信測試號

由於是微信受權,因此必需要在微信環境下使用,首先咱們要在這裏安裝微信開發者工具,由於咱們沒有本身的應用,因此還須要在微信公衆平臺申請一個接口測試號,這個接口測試號就至關於咱們的第三方應用。前端

2. 參數設置

登錄測試號後能夠查看到本身的appId和appsecret信息,將體驗接口權限表裏的網頁服務的網頁受權獲取用戶基本信息修改成127.0.0.1:8800,該地址就是用戶確認受權後回調的地址即咱們應用的後臺處理地址,以下圖node

圖片描述

最後拿出本身微信掃碼關注該測試號便可,以下圖所示git

圖片描述

微信受權流程介紹

具體流程及詳細介紹你們能夠到官網微信公衆平臺技術文檔查看,大體分爲四步:github

  1. 引導用戶進入受權頁面贊成受權,此時會調用微信api獲取code
  2. 受權經過後會帶上code參數請求回調地址
  3. 後臺獲取code,再次調用微信接口換取網頁受權access_token和openid
  4. 經過網頁受權access_token和openid獲取用戶基本信息(若是有unionid還會獲取到unionid參數)

正式開始

詳細代碼能夠在github上下載,地址 https://github.com/wangfengyu...

1. 原始代碼

let express = require("express");
const https = require('https');

let app = express();

//appID
let appID = `wxec6fa9e9bc03d885`;
//appsecret
let appSerect = `4c8a0d14cff08959b4e17334cabf9cf0`;
//點擊受權後重定向url地址
let redirectUrl = `/getUserInfo`;
let host = `http://127.0.0.1:3000`;
//微信受權api,接口返回code,點擊受權後跳轉到重定向地址並帶上code參數
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`;
    //經過拿到的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;
            //經過上一步獲取的access_token和open_id獲取userInfo即用戶信息
            let getUserUrl = `https://api.weixin.qq.com/sns/userinfo?access_token=${access_token}&openid=${open_id}&lang=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);
    });
    // res.end();
});

app.listen(3000);

具體使用時要將appID和appSerect換成你對應的參數便可,由於咱們的請求是要按必定順序的,可是node發送請求是異步的,因此咱們的請求嵌套了三層,代碼很難看,因此這裏能夠採用ES6的async和await解決異步回調地獄。express

2. 使用ES6的async和await的改進代碼

async function wxAuth(req, res) {
    //解析querystring獲取URL中的code值
    let code = req.query.code;
    //經過拿到的code和appID、app_serect獲取返回信息
    let resObj = await getAccessToken(code);
    //解析獲得access_token和open_id
    let access_token = resObj.access_token;
    let open_id = resObj.openid;
    //經過上一步獲取的access_token和open_id獲取userInfo即用戶信息
    let userObj = await getUserInfo(access_token, open_id);
    console.log(userObj);
    res.render(path.resolve(__dirname,'userInfo.ejs'), {userObj: userObj});
    // res.send(userObj);
}


//經過拿到的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);
        });
    });
    
}

//經過上一步獲取的access_token和open_id獲取userInfo即用戶信息
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}&lang=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);
        });
    })
}

app.listen(8800);

修改後代碼流程清晰了不少,最後將獲取到的userObj經過ejs模板渲染在前端頁面,就能看到文章最開始展示的效果圖。api

寫在最後

我前端剛入門沒多久,最近在公司實習,受到身邊同事影響,因此也開始寫文章來記錄本身的學習心得,這是我第一次寫文章,因此可能寫的不太好,你們對文章和代碼有什麼建議歡迎提出來一塊兒交流,謝謝!
相關文章
相關標籤/搜索