专栏首页一Li小麦微信网页开发

微信网页开发

套用《围城》里老学究的的一句开场白:"兄弟我刚入行的时候…“兄弟我是很不喜欢微信这样一款应用的——尽管我在2011年就已经是微信的注册用户。在我看来,第一个,能用qq达到的目的为什么还要微信?其次,凭什么一个开发要绑在一款微信里?但是,周边的人似乎在我毕业的前后通通用上了微信。

我的第一个老板,也非常喜欢微信。她给我第一份工作,就是运营一个微信公众号,持续至今。

我上一个老板,则给我安利了一部叫《创业时代》的商战电视剧。讲的就是另外一条平行世界线里,一款类似微信的语音即时通讯软件创业的故事。

这大概是2007年之后影响我最大的电视剧——尽管这部电视剧只有6分多的评分,尽管我2007年之后没看过电视剧。

扯远了。

本文延续上一讲的程序进行实验。需要安装微信web开发工具。

  1. auth2.0授权
  2. jssdk
  3. 科学算命应用

网页auth2.0鉴权

官方资料 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842 npm库 https://github.com/node-webot/wechat-oauth 阮一峰的OAuth2 http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html

网页授权原理:

(A)用户访问客户端,客户端将前者导向认证服务器。

(B)用户选择是否给客户端授权

(C)如果用户授权,认证服务器将用户导向客户端指定的重定向uri(redirection URI),同时附上授权码

(D)客户端收到授权码,附上之前的重定向uri,向认证服务器申请令牌,

(E)认证服务器核对了授权码和URi,向客户端发送令牌包括访问令牌(access_token)和更新令牌(refresh_token)。

微信做auth2.0认证需要以下信息:

在此处配置你的域名:

配置JS安全接口:

https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432

注意,这里的配置域名都不需要加http://,后面也不能带/

微信授权登录

调用第三方服务器接口—>导向到微信服务器认证—>第三方认证—>成功后回调微信code。

需要引入一个新的co-wecaht-oauth库。

首先我们写一个前端请求方法。比如说,我点击一个按钮,跳转到一个/wxAuthorize下的微信认证页面。然后成功了的话,跳转回/wxCallback那么后端就要写一个路由:

// index.js
const const Oauth=require('co-wechat-oauth');
const oauth=new Oauth(config.appid,config.appsecret);

router.get('/wxAuthorize', async (ctx, next) => {
    //重定向到微信界面
    const state = ctx.query.id;
    // const target = ctx.href
    console.log('ctx...' + ctx.href);

    // 目标地址
    let redirectUrl = ctx.href;
    redirectUrl = redirectUrl.replace('wxAuthorize', 'wxCallback')
    const scope = 'snsapi_userinfo'

    // 导向微信认证页面
    var url = oauth.getAuthorizeURL(redirectUrl, state, scope);
    console.log('url' + url)
    ctx.redirect(url)

})

跳转的接口写一下:

router.get('/wxCallback',async (ctx, next) => {
    const code = ctx.query.code
    console.log('callback:', code)
    const token=await oauth.getAccessToken(code);
    const access_token=token.data.access_token;

    const openid=token.data.openid;
    console.log(token);
    // 接着让丫跳转到一个认证后的界面:带上openid

})

点击用户登录按钮:

同意之后就跳转了wxCallback,还有了一个授权码:

现在我就完成了第一步功能。

认证完了。有了access_token和openid,就可以肆意搞起来了。

获取用户信息

微信用户的公开信息包括:

router.get('/authed',async (ctx,next)=>{

再执行流程:

用户信息就拿到了。

openid对于前端来说是没有用的。真正需要的其实是后端。如果一个后端老是要你发openID给他,那就是他的问题了。因此上面的例子是把openid放到链接里。其实是不合理的。

全局票据的缓存

这里的access_token是和服务器端的access_token不太一样,服务器端的只需要一个就好了。但是网页端的。每个用户登录都会产生一个token。

还是得存在mongodb里。

修改mongoose.js,添加如下内容:

// ClientAccessToken
schema = new Schema({
    access_tokeåån: String,
    expires_in: Number,
    refresh_token: String,
    openid: String,
    scope: String,
    create_at: String
});
// 自定义getToken方法
schema.statics.getToken = async function (openid) {
    return await this.findOne({
        openid: openid
}); };
schema.statics.setToken = async function (openid, token) { // 有则更新,无则添加
const query = {
        openid: openid
    };
    const options = {
        upsert: true
};
    return await this.updateOne(query, token, options);
};
exports.ClientToken = mongoose.model('ClientToken', schema);

上面这一段添加了两个方法:查询和更新。

然后在new出Oauth的时候调用这两个方法:

const { ServerToken, ClientToken } = require('./mongoose');
const Oauth = require('co-wechat-oauth');
const oauth = new Oauth(
    config.appid,
    config.appsecret,
    async function (openid) {
        return await ClientToken.getToken(openid)
    },
    async function (openid, token) {
        return await ClientToken.setToken(openid, token)
    }
);

好了。你每次登录之后,就产生了一个token存到了mongo的clienttoken表里了。如果你要调用,就可以使用ClientToken.getToken(openid)获取。

微信JS-SDK

官方资料:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 npm库: https://github.com/node-webot/co-wechat-api

所谓微信JS-SDK,就是微信公众平台 面向网页开发者提供的基于微信内的网页开发工具包。node操作这个,已经有封装好的调用了,就是上一讲的co-wechat-api。

通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。

简单说,网页想调用设备端的一些特性?微信帮你做。前提是获得授权。这个过程是微信认证我们开发的网页。

微信给前端的设备能力(扫码可看):

我们看文档:

首先是配置jssdk,然后是引入js文件http://res.wx.qq.com/open/js/jweixin-1.4.0.js(前两步已做),会生成一个wx对象。接下来就是在前端做配置:

wx.config({
    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: '', // 必填,公众号的唯一标识
    timestamp: , // 必填,生成签名的时间戳
    nonceStr: '', // 必填,生成签名的随机串
    signature: '',// 必填,签名
    jsApiList: [] // 必填,需要使用的JS接口列表
});

问题在于,这些乱七八糟的东西前端都没有。

获取配置

写一个请求方法和接口:

// 前端
const res=await axios.get('/getJsConfig',{
    params:{
          //把你的url参数带上!
        url:window.location.href
    }
});
console.log(res.data)

//后端
router.get('/getJsConfig', async ctx => {
    console.log('getJSSDK...', ctx.query)
    var res = await api.getJsConfig(ctx.query);
    console.log('res', res)
    ctx.body = res
})

申请权限

拿到配置后,我们继续修改前端要让网页拿到onMenuShareTimelineonMenuShareAppMessage的授权:

res.data.jsApiList = ['onMenuShareTimeline', 'onMenuShareAppMessage']
wx.config(res.data);
wx.ready(function (e) {
    console.log('wx.ready......',e)
});

jsApiList参考 https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115 附录2

在微信开发者工具上看到:

接口就申请成功了。

实例:科学算命

现在一个乙方给你一个任务:我要做一个科学算命的应用。需要分享之后才能看到结果。应该怎么搞?

首先是点击get一个路由/test_wxAuthorize,登录后跳转share.html

router.get('/test_wxAuthorize', async (ctx, next) => {
    const state = ctx.query.id;
    // 目标地址
    let redirectUrl = ctx.href;
    redirectUrl = redirectUrl.replace('wxAuthorize', 'share.html')
    const scope = 'snsapi_userinfo'

    // 导向微信认证页面
    var url = oauth.getAuthorizeURL(redirectUrl, state, scope);
    ctx.redirect(url)
});

然后让他跳转到test_share.html:

router.get('/test_wxAuthorize', async (ctx, next) => {
    const state = ctx.query.id;
    // 目标地址
    let redirectUrl = ctx.href;
    redirectUrl = redirectUrl.replace('wxAuthorize', 'share.html')
    const scope = 'snsapi_userinfo'

    // 导向微信认证页面
    var url = oauth.getAuthorizeURL(redirectUrl, state, scope);
    ctx.redirect(url)
});

写下这个页面吧:

<!--test_share.html-->
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
    <script src="https://unpkg.com/vue@2.1.10/dist/vue.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://unpkg.com/cube-ui/lib/cube.min.js"></script>
    <script src="https://cdn.bootcss.com/qs/6.6.0/qs.js"></script>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.4.0.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/cube-ui/lib/cube.min.css">
    <style>
        /* .cube-btn {
            margin: 10px 0;
        } */
    </style>
</head>

<body>
    <div id="app">
        <div>右上角分享到朋友圈后看答案</div>
        <p>我家的mbp提供云计算服务</p>
    </div>
    <script>
        var app = new Vue({
            el: '#app',
            data: {
                value: 'input'
            },

            methods: {
                getQueryVariable(variable) {
                    var query = window.location.search.substring(1);
                    var vars = query.split("&");
                    for (var i = 0; i < vars.length; i++) {
                        var pair = vars[i].split("=");
                        if (pair[0] == variable) { return pair[1]; }
                    }
                    return (false);
                }
            },
            mounted: async function () {
                //用户信息
                const code = this.getQueryVariable('code');
                let userInfo=await axios.get(`/userInfo?code=${code}`);
                userInfo=userInfo.data;

                //测试结果
                const _res = await axios.get('/getTest')
                let num = _res.data;

                // 获取配置
                const res = await axios.get('/getJsConfig', {
                    params: {
                        url: window.location.href
                    }
                })

                // jssdk权限:分享给朋友,分享给个人
                res.data.jsApiList = ['onMenuShareTimeline', 'onMenuShareAppMessage']
                wx.config(res.data);
                wx.ready(function (e) {
                    console.log('wx.ready......', e)
                    let conf = {
                        title: `震惊!原来${userInfo.nickname}的命运是这样的...`, // 分享标题
                        link: 'http://djtao.free.idcfengye.com/test_wxAuthorize', // 分享链接
                        imgUrl: userInfo.headimgurl, // 分享图标
                        success: async function () {
                            window.location.href = `/server/${num}.html`
                        }
                    }
                    wx.onMenuShareTimeline(conf)
                });
            },
        });
    </script>
</body>
</html>

我曾经无聊爬取了51支签及其解读(html)格式,分为1-51.html在server文件夹下,刚好可以用来求签。

补充接口:

router.get('/test_wxAuthorize', async (ctx, next) => {
    const state = ctx.query.id;
    // 目标地址
    let redirectUrl = ctx.href;
    redirectUrl = redirectUrl.replace('wxAuthorize', 'share.html')
    const scope = 'snsapi_userinfo'

    // 导向微信认证页面
    var url = oauth.getAuthorizeURL(redirectUrl, state, scope);
    ctx.redirect(url)
});
//科学算命核心接口
router.get('/getTest',async (ctx,next)=>{
    var num=Math.round(Math.random()*51);
    // let data=fs.readFileSync(`server/${num}.html`)
    // console.log(data);
    ctx.body=num;
})

那么功能就完成了。

这种病毒式应用要少搞,搞了会封号的。

本文分享自微信公众号 - 一Li小麦(gh_c88159ec1309),作者:一li小麦

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-08

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 前后端权限机制

    本项目使用vue全家桶,axios和cube-ui cube-ui文档地址:https://didi.github.io/cube-ui/#/zh-CN/doc...

    一粒小麦
  • koa实践及其手撸

    Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石...

    一粒小麦
  • 那些年初级前后端一起撕过的逼

    一个项目一开始总是出于还不错愿景,但做着做着,就越来越乱了。万丈高楼平地起,有些基础的问题解决好,后面改需求就不会那么痛苦了。

    一粒小麦
  • koa框架生成微信公众号二维码

    demo的github地址:https://github.com/xuedingmiaojun/koa-demo.git

    薛定喵君
  • vue+node+mongodb 搭建一个完整博客

    前段时间刚把自己的个人网站写完, 于是这段时间因为事情不是太多,便整理了一下,写了个简易版的博客系统 服务端用的是 koa2框架 进行开发

    前端博客 : alili.tech
  • 【门票福利】2019产品经理年度大会·北京站

    当我们盘点这些年互联网的发展轨迹,会发现产品、运营的发展趋势一直在变化: 2015年共享经济大行其道,我们讲共享经济,消费互联网; 2016年消费升级,我们知...

    腾讯大讲堂
  • 寻找质数—埃式筛法

    这个题,用暴力法肯定会超时,优化一点的暴力法还是会超时。一般来说,寻找质数主要是两种方法,埃式筛和欧拉筛。

    生信编程日常
  • 以小白的角度解读Koa源码

    使用Koa已有一段时间,为什么会从Express转向Koa呢,那还是得从Express上说起。对于服务端的Web框架来说,Express更为贴近「Web Fra...

    JowayYoung
  • 慕课网Flask构建可扩展的RESTful API-5. Token与HTTPBasic验证 —— 用令牌来管理用户

    与网站登录不同的是,网站登录将登录信息写入cookie存储在浏览器,而API只负责生成token发送给客户端,而客户端怎么存储有自己决定。

    Meet相识
  • day102-day104-Linux基本命令

    <><><><><><><><><><><><><><><><><><><><>分割线<><><><><><><><><><><><><><><><><><><...

    少年包青菜

扫码关注云+社区

领取腾讯云代金券