微信网页授权并获取用户信息的方法


Posted in Javascript onJuly 30, 2018

介绍

在很多微信H5应用里,当用户访问第三方应用时就需要进行微信网页授权,并且很多涉及安全的操作我们必须要先获取用户信息才能继续,本文章简单介绍了微信授权流程,并通过申请微信测试账号来模拟网页授权,用户在授权页点击确定登录后获取用户信息并显示在前端页面,最后效果如下图

微信网页授权并获取用户信息的方法

工具及开发准备

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

因为是微信授权,所以必须要在微信环境下使用,首先我们要在这里安装微信开发者工具,因为我们没有自己的应用,所以还需要在微信公众平台申请一个接口测试号,这个接口测试号就相当于我们的第三方应用。 

2. 参数设置

登陆测试号后可以查看到自己的appId和appsecret信息,将体验接口权限表里的网页服务的网页授权获取用户基本信息修改为127.0.0.1:8800,该地址就是用户确认授权后回调的地址即我们应用的后台处理地址,如下图

微信网页授权并获取用户信息的方法

最后拿出自己微信扫码关注该测试号即可,如下图所示

微信网页授权并获取用户信息的方法

微信授权流程介绍

具体流程及详细介绍大家可以到官网微信公众平台技术文档查看,大致分为四步:  

1. 引导用户进入授权页面同意授权,此时会调用微信api获取code

2. 授权通过后会带上code参数请求回调地址

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

4. 通过网页授权access_token和openid获取用户基本信息(如果有unionid还会获取到unionid参数)

正式开始

详细代码可以在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}⟨=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}⟨=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模板渲染在前端页面,就能看到文章最开始展现的效果图。

写在最后

我前端刚入门没多久,最近在公司实习,受到身边同事影响,所以也开始写文章来记录自己的学习心得,这是我第一次写文章,所以可能写的不太好,大家对文章和代码有什么建议欢迎提出来一起交流,谢谢!也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
checkbox 多选框 联动实现代码
Oct 22 Javascript
jquery $.ajax各个事件执行顺序
Oct 15 Javascript
jquery用get实现ajax在ie里面刷新不进入后台解决方法
Aug 12 Javascript
jQuery中prepend()方法用法实例
Dec 25 Javascript
ECMAScript6中Map/WeakMap详解
Jun 12 Javascript
JS实现黑客帝国文字下落效果
Sep 01 Javascript
属于你的jQuery提示框(Tip)插件
Jan 20 Javascript
JS对象是否拥有某属性如何判断
Feb 03 Javascript
vue使用watch 观察路由变化,重新获取内容
Mar 08 Javascript
详解50行代码,Node爬虫练手项目
Apr 22 Javascript
vue 返回上一页,页面样式错乱的解决
Nov 14 Javascript
基于node+vue实现简单的WebSocket聊天功能
Feb 01 Javascript
axios简单实现小程序延时loading指示
Jul 30 #Javascript
JS实现HTML页面中动态显示当前时间完整示例
Jul 30 #Javascript
JS实现DOM节点插入操作之子节点与兄弟节点插入操作示例
Jul 30 #Javascript
js+html5实现手机九宫格密码解锁功能
Jul 30 #Javascript
vscode中vue-cli项目es-lint的配置方法
Jul 30 #Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
Jul 30 #Javascript
JavaScript笛卡尔积超简单实现算法示例
Jul 30 #Javascript
You might like
使用php+xslt在windows平台上
2006/10/09 PHP
比较全面的PHP数组的使用方法小结
2010/09/23 PHP
PHP扩展CURL的用法详解
2014/06/20 PHP
ThinkPHP惯例配置文件详解
2014/07/14 PHP
php获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
PHP实现加强版加密解密类实例
2015/07/29 PHP
WordPress中获取所使用的模板的页面ID的简单方法
2015/12/31 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
2020/08/26 PHP
用window.location.href实现刷新另个框架页面
2007/03/07 Javascript
javascript与asp.net(c#)互相调用方法
2009/12/13 Javascript
类似GMAIL的Ajax信息反馈显示
2010/02/16 Javascript
jquery三个关闭弹出层的小示例
2013/11/05 Javascript
jquery插件之定时查询待处理任务数量
2014/05/01 Javascript
Juery解决tablesorter中文排序和字符范围的方法
2015/05/06 Javascript
学习JavaScript设计模式之中介者模式
2016/01/14 Javascript
jQuery模仿单选按钮选中效果
2016/06/24 Javascript
JavaScript基于对象去除数组重复项的方法
2016/10/09 Javascript
解决JSON.stringify()自动将中文转译成unicode的问题
2018/01/05 Javascript
深入分析element ScrollBar滚动组件源码
2019/01/22 Javascript
详解ES7 Decorator 入门解析
2019/02/18 Javascript
仿ElementUI实现一个Form表单的实现代码
2019/04/23 Javascript
改进 JavaScript 和 Rust 的互操作性并深入认识 wasm-bindgen 组件
2019/07/13 Javascript
js简单粗暴的发布订阅示例代码
2021/01/23 Javascript
[02:22]《新闻直播间》2017年08月14日
2017/08/15 DOTA
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
python3 拼接字符串的7种方法
2018/09/12 Python
python线程的几种创建方式详解
2019/08/29 Python
Python使用tkinter实现摇骰子小游戏功能的代码
2020/07/02 Python
Manuka Doctor美国官网:麦卢卡蜂蜜和蜂毒护肤
2016/12/25 全球购物
法国和欧洲海边和滑雪度假:Pierre & Vacances
2017/01/04 全球购物
商场活动策划方案
2014/01/24 职场文书
2015年元旦标语大全
2014/12/09 职场文书
基于docker安装zabbix的详细教程
2022/06/05 Servers
postgresql之greenplum字符串去重拼接方式
2023/05/08 PostgreSQL