微信网页受权并获取用户信息

 介绍 

在不少微信H5应用里,当用户访问第三方应用时就须要进行微信网页受权,而且不少涉及安全的操做咱们必需要先获取用户信息才能继续,本文章简单介绍了微信受权流程,并经过申请微信测试帐号来模拟网页受权,用户在受权页点击肯定登陆后获取用户信息并显示在前端页面,最后效果以下图 html


工具及开发准备 

1. 微信开发者工具及微信测试号 

由于是微信受权,因此必需要在微信环境下使用,首先咱们要在这里安装微信开发者工具,由于咱们没有本身的应用,因此还须要在微信公众平台申请一个接口测试号,这个接口测试号就至关于咱们的第三方应用。 前端

2. 参数设置

 登录测试号后能够查看到本身的appId和appsecret信息,将体验接口权限表里的网页服务的网页受权获取用户基本信息修改成127.0.0.1:8800,该地址就是用户确认受权后回调的地址即咱们应用的后台处理地址,以下图node


 最后拿出本身微信扫码关注该测试号便可,以下图所示git

 

微信受权流程介绍 

具体流程及详细介绍你们能够到官网微信公众平台技术文档查看,大体分为四步:  github

1. 引导用户进入受权页面赞成受权,此时会调用微信api获取code express

 2. 受权经过后会带上code参数请求回调地址  api

3. 后台获取code,再次调用微信接口换取网页受权access_token和openid  安全

4. 经过网页受权access_token和openid获取用户基本信息(若是有unionid还会获取到unionid参数)bash

正式开始  

详细代码能够在github上下载,地址https://github.com/wangfengyuan/wxAuthorize 

 1. 原始代码

let express = require("express");const https = require('https');
let app = express();
//appIDlet 
appID = `wxec6fa9e9bc03d885`;
//appsecretlet 
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);
    }); 

app.listen(3000);复制代码

具体使用时要将appID和appSerect换成你对应的参数便可,由于咱们的请求是要按必定顺序的,可是node发送请求是异步的,因此咱们的请求嵌套了三层,代码很难看,因此这里能够采用ES6的async和await解决异步回调地狱。 

 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);
        });
    })}复制代码

修改后代码流程清晰了不少,最后点击确认登录后将获取到的userObj经过ejs模板渲染在前端页面,就能看到文章最开始展示的效果图。  

写在最后 

我前端刚入门没多久,最近在公司实习,受到身边同事影响,因此也开始写文章来记录本身的学习心得,这是我第一次写文章,因此可能写的不太好,你们对文章和代码有什么建议欢迎提出来一块儿交流,谢谢!
相关文章
相关标签/搜索