打开微信公众平台 https://mp.weixin.qq.com/,使用邮箱注册。
注意,一个邮箱只能注册一个微信公众平台账号,一个账号只能选择一种账号分类且不能更改,这里一定要慎重,要选择自己需要的账户类型。
这里我选择「服务号」。
可选个人类型、企业类型等等,其中,个人类型是没有分享定制功能的。
微信公众号里面,提供一个功能全开的测试账号,使用测试账号可以进行学习和测试,还是没问题的。
填写信息,绑定微信,注册完成,登录进去。
开发阶段可以使用微信提供的测试账号,毕竟很多功能都需要公司资质,或者需要申请流程,比较麻烦,这里开发时就先使用微信提供的公众平台测试账号。
但注意,测试账号没有提供所有功能,比如「微信扫码登录」功能就无法使用测试账号来开发。
进入公众号开发页面,开发 -> 开发者工具,这个页面可以看到几个链接,选择 公众平台测试账号 进入。
进入后,可以看到测试账号的信息:
「测试账号信息」,中的 appID 和 appsecret 自动提供,复制走直接使用。
「接口配置信息」,需要你提供一个 get 接口地址和一个 token,当你点击提交时,微信会调用这个接口,根据你的返回值来判断这个地址是否可用,从而断定这个服务器是否是真正属于你的,接口的实现请参考后面的消息接口使用指南。
「js 安全域名」,是指当你的前端页面需要使用 微信 JSSDK 时,你的前端网站就需要和微信有交互,在这里配置的域名,将认为是属于你这个开发者的网站,在此处添加你的要使用微信sdk功能的网站的域名,比如 wx.qq.com
或者 wx.qq.com/user
,最多可写三个,且需要验证。
验证的方式:就是将一个微信提供的txt文件,放在此域名对应的放置于服务器中的web项目的访问根目录中,需要和主文件(大部分默认为index.html
)放在同一级,当提交的时候,微信会进行访问,来获取文件,确认此域名是你的。
其他的具体可查看 微信JSSDK开发文档。
「测试号二维码」,因为这个是测试账号,并不是微信公开的,所以微信也提供了这个测试账号的测试公众号,功能都需要测试人员关注这儿公众号后,才可以使用。
「接口配置信息」一项,接口实现的代码示例:
const crypto = require('crypto') // 引入加密模块
const config = require('./config') // 引入配置文件
// 提供给微信调用
exports.forWx = async function (query) {
// 1.获取微信服务器Get请求的参数 signature、timestamp、nonce、echostr
const {
signature, // 微信加密签名
timestamp, // 时间戳
nonce, // 随机数
echostr, // 随机字符串
} = query
// 2.将token、timestamp、nonce三个参数进行字典序排序
let array = [config.token, timestamp, nonce]
array.sort()
// 3.将三个参数字符串拼接成一个字符串进行sha1加密
let tempStr = array.join('')
const hashCode = crypto.createHash('sha1') //创建加密类型
let resultCode = hashCode.update(tempStr, 'utf8').digest('hex') //对传入的字符串进行加密
// 4.开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
if (resultCode === signature) {
return echostr
} else {
return 'mismatch'
}
}
滚动测试账号页面到「体验接口权限表」模块,罗列了这个测试账号能提供测试的功能们,有一些功能需要在里面再配置一下,比如我们现在需要的「网页授权(微信打开页面,使用微信登录)」功能,就需要设置一下重定向的域名。
注意这里的域名,不需要填写协议,比如直接写「www.baidu.com」。
这个域名需要和后面的开发时,用户允许登录时写的域名一致,如果这里没有配置,就算用户登录完,也无法正确的跳转过去。
后续步骤需要用代码开发前端和后端代码了,可参考 官方文档。
主要流程也比较简单。
当需要用户授权登录时,需要跳转页面,跳转页面的格式如下:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
其中的「APPID」、「redirect_uri」、「scope」、「state」四个参数,需要自己填上。
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 公众号的唯一标识 |
redirect_uri | 是 | 授权后重定向的回调链接地址, 请使用 urlEncode 对链接进行处理 |
response_type | 是 | 返回类型,请填写code |
scope | 是 | 应用授权作用域:snsapi_base (不弹授权页面,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地 ) |
state | 否 | 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 |
#wechat_redirect | 是 | 无论直接打开还是做页面302重定向时候,必须带此参数 |
代码示例:
一下为 node 代码,query 是前端调用时,传入的参数,此方法最终返回拼接好的需要前端跳转的 url。
const config = require('./config') // 引入配置文件
// 获取微信授权 --- code
exports.getOauth2 = async function(query) {
let { redirect_uri, state } = query
// 第一步:用户同意授权,获取code
// type:snsapi_base // 不弹出授权页面,直接跳转,只能获取用户openid
// type:snsapi_userinfo // 弹出授权页面,可通过openid拿到昵称、性别、所在地
let scope = 'snsapi_userinfo'
let baseUrl = config.authorize; // 弹出授权页面,拿到code
let url = `${baseUrl}?appid=${config.appId}&redirect_uri=${redirect_uri}&response_type=code&scope=${scope}${state ? '&state=' + state : ''}#wechat_redirect`
return JSON.stringify({success: true, data: url})
}
如果 scope 为 snsapi_userinfo 这个会弹出授权页面的值,那么就会出现以下弹框提示:
选择允许后,微信会跳转到 redirect_uri 页面,并把 code 和 state 作为页面参数传入,我们通过 url 便可拿到用户的 code。
code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
有了用户 code,我们需要用这个临时 code,调用微信接口换为用户 的 access_token。
调用以下接口:
GET https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
url 中参数意义:
参数 | 是否必须 | 说明 |
---|---|---|
appid | 是 | 公众号的唯一标识 |
secret | 是 | 公众号的appsecret |
code | 是 | 填写第一步获取的code参数 |
grant_type | 是 | 填写为authorization_code |
调用之后,微信就会返回该用户的 access_token 和用户唯一标识 openid 了。
接口也会提供一个用户的 refresh_token,这是由于access_token 拥有较短的有效期,当access_token超时后,可以使用refresh_token进行刷新,refresh_token有效期为30天,当refresh_token失效之后,需要用户重新授权。
刷新 access_token 也是调用一个接口,这里不再详解。
代码示例:
../util/request 为我自己封装的 node 的 get 请求。
const config = require('./config') // 引入配置文件
const { https } = require('../util/request')
const qs = require('qs')
// 通过 code 获取 openId 和 access_token
async function getOpenIdAndAccessToken (code) {
let params = {
appid: config.appId,
secret: config.appSecret,
code,
grant_type: 'authorization_code'
}
let url = `https://api.weixin.qq.com/sns/oauth2/access_token?${qs.stringify(params)}`
let bodyObj = await https(url)
return JSON.parse(bodyObj)
}
注意: 只有之前的 scope 为 snsapi_userinfo 时,这一步才能调通,否则没有权限。
调用以下接口:
GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN
参数说明
参数 | 描述 |
---|---|
access_token | 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 |
openid | 用户的唯一标识 |
lang | 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 |
就可以拿到用户信息了。
代码示例:
最终可以拿到用户的个人信息了。
const { https } = require('../util/request')
// 获取用户信息
async function getUserInfoFromWx ({ access_token, openid }) {
let params = {
access_token,
openid,
lang: 'zh_CN'
};
let url = `https://api.weixin.qq.com/sns/userinfo?${qs.stringify(params)}`
let body = await https(url)
return JSON.parse(body)
}