引言
此篇文章主要涉及以下内容:
公众号网页授权方法
Oauth2原理
JSSDK调用方法
网页授权
(A)用户访问客户端,后者将前者导向认证服务器。
(B)用户选择是否给予客户端授权。
(C)假设用户给予授权,认证服务器将用户导向客户端事先指定的"重定向URI"(redirection URI),同时附上一个授权码。
(D)客户端收到授权码,附上早先的"重定向URI",向认证服务器器申请令牌。这一步是在客户端的后台的服务器上完成的,对用户不可见。
(E)认证服务器核对了授权码和重定向URI,确认无误后,向客户端发送访问令牌(access token)和更新令牌(refresh token)。基于SPA的网页授权流程 https://www.jianshu.com/p/27b8069b4178获取用户信息 - 相当于普通网页的用户登录。
配置网页回调
image.png
配置JS安全接口
image.png
网页端
网页授权
微信登录
获取⽤用户信息
// wechat/index.html
async auth () {
window.location.href = '/wxAuthorize'
},
初始化Oauth
// index.js
const OAuth = require('co-wechat-oauth');
const oauth = new OAuth(conf.appid, conf.appsecret);
生成用户URL
// index.js
// ⽣生成引导⽤用户点击的 URL
router.get("/wxAuthorize", async (ctx, next) => {
const state = ctx.query.id;
// const target = ctx.href
console.log("ctx..." + ctx.href);
// ⽬目标地址
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);
});
获取用户回调 AccessToken与OpenId
// index.js
// 获取AccessToken
router.get("/wxCallback", async (ctx, next) => {
const code = ctx.query.code; // 授权码
console.log("getAccessToken", code);
var token = await oauth.getAccessToken(code);
var accessToken = token.data.access_token;
var openid = token.data.openid;
console.log("getAccessToken....");
console.log("accessToken", accessToken);
console.log("openid", openid);
// ctx.body = token
ctx.redirect("/?openid=" + openid);
});
用户信息
// index.html
async getUser(){
const qs = Qs.parse(window.location.search.substr(1))
const openid = qs.openid
const res = await axios.get(`/getUser`,{
params:{
openid
}
})
console.log('User',res.data)
},
// index.js
router.get('/getUser', async (ctx, next) => {
const openid = ctx.query.openid
console.log('getUser', openid)
var userInfo = await oauth.getUser(openid);
console.log('userInfo:', userInfo)
ctx.body = userInfo
})
AccessToken缓存问题
// mongo.js
// ClientAccessToken
// mongoose.js
const mongoose = require("mongoose");
const { Schema } = mongoose;
mongoose.connect(
"mongodb://localhost:27017/weixin",
{
useNewUrlParser: true,
},
() => {
console.log("Mongodb connected..");
}
);
exports.ServerToken = mongoose.model("ServerToken", {
accessToken: String,
});
// ClientAccessToken
schema = new Schema({
access_token: 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);
const OAuth = require("co-wechat-oauth");
const oauth = new OAuth(
conf.appid,
conf.appsecret,
async function(openid) {
return await ClientToken.getToken(openid);
},
async function(openid, token) {
return await ClientToken.setToken(openid, token);
}
);
微信JSSDK
运行于微信内置浏览器网页
调用微信原生应用如:拍照、语音、扫一扫
分享功能 查到的数据不同
图像接口
音频接口
// index.js
// 获取JSConfig
router.get("/getJsConfig", async ctx => {
console.log("getJSSDK...", ctx.query);
var res = await api.getJsConfig(ctx.query);
console.log("res", res);
ctx.body = res;
});
// index.html
// index.html
getJSConfig: async function() {
console.log('wx:', wx)
let res = await axios.get('/getJSConfig', {
params: {
url: window.location.href
}
})
console.log('res.......', res.data)
res.data.jsApiList = ['onMenuShareTimeline',
'onMenuShareAppMessage']
wx.config(res.data);
wx.ready(function () {
console.log('wx.ready......')
});
// 获取网络地址
wx.getNetworkType({
success: function (res) {
// 返回网络类型2g,3g,4g,wifi
var networkType = res.networkType;
console.log('getNetworkType...', networkType)
}
});
}
你的赞是我前进的动力
求赞,求评论,求转发...