Skip to main content

README

示例文件

微信服务端代码链接: https://pan.baidu.com/s/1aFebiga-8Q3rSNhEMadJYg 提取码: reql

前提:网页授权(非静默授权)

image.png

文档地址:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

原理:共三步

前提:绑定公众号拿到appid和sercet值 appid注意测试的话写测试的appid,正式的话写正式的appid,不要写错了。

  1. 根据 appid 和 sercet 换取code (前端:code是动态变化,每次获取都需要清除缓存重新请求)
  2. 根据 code 换取 access_token和openid (服务端)
  3. 根据 access_token 和 openid 换取 用户数据(服务端)

#示例:船票DEMO

前端

index.html

<!DOCTYPE html>
<html>

<head>
<title>2021,送你一张船票</title>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta name="viewport"
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="full-screen" content="true">
<meta name="x5-fullscreen" content="true">
<meta name="360-fullscreen" content="true">
<meta name="laya" screenorientation="landscape">
<meta http-equiv="expires" content="0">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="expires" content="0">
<meta http-equiv="Cache-Control" content="no-siteapp">
<!-- 引擎jQuery库 -->
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.js"/>
<!-- 第一步:根据 appid和sercet 换取code (前端) -->
<script>
//获取url路径中指定key的value值
//例如url路径: http://172.30.21.29:3000/?code=001XQh0006bLCM1RLx100TAmgB2XQh0D&state=STATE
//获取code的值 001XQh0006bLCM1RLx100TAmgB2XQh0D
function getQueryString(name) {
let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
let r = window.location.search.substr(1).match(reg);
if (r != null) {
return decodeURIComponent(r[2]);
};
return null;
}

//声明code
var code

//设置code
if(localStorage.getItem("code")){// 如果本地缓存已经存有code 说明是回退到了获取code的起始页面
code = localStorage.getItem("code");
console.log("code",code);
alert('我是从本地缓存取的code:'+code)

} else if(getQueryString("code")){ // 本地无code,查询URL链接上是否存在code,存在说明是获取code的当前页面
code = getQueryString("code");
localStorage.setItem("code",code);
alert('我是获取code的页面从url取的code: ',code)

} else {// 都不没有code,跳转页面发起请求(要去微信指定链接获取)
window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx381145d57357ff23&redirect_uri=${encodeURIComponent(window.location.href)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
}

//调用后台接口请求页面(传递参数)获取用户数据(后两步在服务器完成)
if(code){
console.log('/api/wx/userinfo?code=' + code)
//发起后台请求
$.get('/api/wx/userinfo?code=' + code, function (data, status) {
// alert("数据:" + data + "\n状态:" + status);
console.log(data)
});
}

//简易版()
// var code = getQueryString("code")

// if (!code) {
// window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx381145d57357ff23&redirect_uri=${encodeURIComponent(window.location.href)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
// } else {
// //发起后台请求获取token和openid
// console.log('/api/wx/userinfo?code=' + code)
// $.get('/api/wx/userinfo?code=' + code, function (data, status) {
// // alert("数据:" + data + "\n状态:" + status);
// console.log(data)
// });
// }
</script>
</head>

<body>
...
</body>
</html>

服务端(nodejs)

开启服务器:通过koa-static本地展示静态文件

wechat.js

const moment = require('moment');
const request = require('../../common/request');
const wxService = require('../../services/wechat/wechat');

exports.userinfo = {
path: '/api/wx/userinfo',
method: 'get',
online: true,
handler: async ctx => { //handler为卿哥封装后的接口

//koa语法:ctx.query--学习(看koa)
//前端获取code展示在url,后端通过url获取code
let code = ctx.query.code;

///第二步: 根据code换取 access_token 和 openid
var url = `https://api.weixin.qq.com/sns/oauth2/access_token?appid=wx381145d57357ff23&secret=cbed33d90bc25be44bd219188c4a94c4&code=${code}&grant_type=authorization_code`
//发起异步请求
let tokenData = await request.get({ url, json: true });
// console.dir(tokenData)

//access_token和openid参考数据格式
// {
// "access_token":"ACCESS_TOKEN",
// "expires_in":7200,
// "refresh_token":"REFRESH_TOKEN",
// "openid":"OPENID",
// "scope":"SCOPE"
// }

//第三步:根据 access_token 和 openid 换取 用户数据
var url2 = `https://api.weixin.qq.com/sns/userinfo`
//防止转译:防止输入URL进行数据转译
let qs = {
access_token: tokenData.access_token,
openid: tokenData.openid,
lang: 'zh_CN'
}
//发起异步请求
const userinfo = await request.get({ url: url2, qs, json: true }); //注意,请求时不要简写明确书写{key:value} //qs自动拼接到url后
ctx.json(userinfo)

/*用户参考数据格式
{
code: 0
data: {
city: ""
country: "中国"
headimgurl: "https://thirdwx.qlogo.cn/mmopen/vi_32/KGbtdeBaq0bUbAEegficu81SNDh0zJBpwkKibkyhj1Kzn96ib1TgQicnt9iciaNNncFiblEZicuxXNgEmfGPxicLN59xjsg/132"
language: "zh_CN"
nickname: "迦南🍃"
openid: "ojFbV6CPdtkPTRswOEg8Cf9IxXjs"
privilege: []
province: ""
sex: 1
}
message: "成功"
}
*/
},
};

大鱼新年签

步骤一:微信开放平台-第三方平台-详情-开发配置,完成权限集与开发资料的配置。(用户appid/scope)

步骤二:调用接口获取授权码(code),并添加回调页面URL

 // 微信拉起授权案例 
const callback = encodeURIComponent(
`https://id.ifeng.com/sso/v1/?redirect=${encodeURIComponent(
'https://news.ifeng.com/loc/bigFishNewYearSign/draw'
)}`
);

window.location.replace(`https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx9bd3b38f9c278ab4&redirect_uri=${callback}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`)

步骤三:用户同意授权,本地存入code, 发起请求用户数据

const getUserData = async code => {
return await jsonp(`https://user.iclient.ifeng.com/Api_User_Userbasic/weixinLogin?code=${code}&proid=weixinh5`, {
data: { code },
jsonpCallback: createJsonpCallbackName('getUserData'),
cache: false,
});
};

步骤四:服务端返回用户数据。

链接

微信公众号开发:获取openId和用户信息