编程崽

登录

一叶在编程苦海沉沦的扁舟之上,我是那只激情自射的崽

微信手机打开的页面中授权登录

微信手机打开的页面中授权登录

注册登录

打开微信公众平台 https://mp.weixin.qq.com/,使用邮箱注册。

注意,一个邮箱只能注册一个微信公众平台账号,一个账号只能选择一种账号分类且不能更改,这里一定要慎重,要选择自己需要的账户类型。

eff4a9eadfe7fcba51cbe0cc6b9016b0.png

这里我选择「服务号」。

可选个人类型、企业类型等等,其中,个人类型是没有分享定制功能的。

微信公众号里面,提供一个功能全开的测试账号,使用测试账号可以进行学习和测试,还是没问题的。

填写信息,绑定微信,注册完成,登录进去。

使用测试账号开发

开发阶段可以使用微信提供的测试账号,毕竟很多功能都需要公司资质,或者需要申请流程,比较麻烦,这里开发时就先使用微信提供的公众平台测试账号。

但注意,测试账号没有提供所有功能,比如「微信扫码登录」功能就无法使用测试账号来开发。

进入公众号开发页面,开发 -> 开发者工具,这个页面可以看到几个链接,选择 公众平台测试账号 进入。

Snipaste_2021-03-23_17-43-27.png

进入后,可以看到测试账号的信息:

  • 「测试账号信息」,中的 appID 和 appsecret 自动提供,复制走直接使用。

  • 「接口配置信息」,需要你提供一个 get 接口地址和一个 token,当你点击提交时,微信会调用这个接口,根据你的返回值来判断这个地址是否可用,从而断定这个服务器是否是真正属于你的,接口的实现请参考后面的消息接口使用指南

  • 「js 安全域名」,是指当你的前端页面需要使用 微信 JSSDK 时,你的前端网站就需要和微信有交互,在这里配置的域名,将认为是属于你这个开发者的网站,在此处添加你的要使用微信sdk功能的网站的域名,比如 wx.qq.com 或者 wx.qq.com/user,最多可写三个,且需要验证。

    验证的方式:就是将一个微信提供的txt文件,放在此域名对应的放置于服务器中的web项目的访问根目录中,需要和主文件(大部分默认为index.html)放在同一级,当提交的时候,微信会进行访问,来获取文件,确认此域名是你的。

    其他的具体可查看 微信JSSDK开发文档。

  • 「测试号二维码」,因为这个是测试账号,并不是微信公开的,所以微信也提供了这个测试账号的测试公众号,功能都需要测试人员关注这儿公众号后,才可以使用。

「接口配置信息」一项,接口实现的代码示例:

js 复制代码
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'
  }
}

Snipaste_2021-03-23_17-49-17.png

开发微信端授权登录

滚动测试账号页面到「体验接口权限表」模块,罗列了这个测试账号能提供测试的功能们,有一些功能需要在里面再配置一下,比如我们现在需要的「网页授权(微信打开页面,使用微信登录)」功能,就需要设置一下重定向的域名。

注意这里的域名,不需要填写协议,比如直接写「www.baidu.com」。

这个域名需要和后面的开发时,用户允许登录时写的域名一致,如果这里没有配置,就算用户登录完,也无法正确的跳转过去。

Snipaste_2021-03-23_17-59-36.png

后续步骤需要用代码开发前端和后端代码了,可参考 官方文档

主要流程也比较简单。

跳转微信授权页面

当需要用户授权登录时,需要跳转页面,跳转页面的格式如下:

sh 复制代码
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。

js 复制代码
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})
}

如果 scopesnsapi_userinfo 这个会弹出授权页面的值,那么就会出现以下弹框提示:

Snipaste_2021-03-26_14-25-24.png

选择允许后,微信会跳转到 redirect_uri 页面,并把 code 和 state 作为页面参数传入,我们通过 url 便可拿到用户的 code。

code说明 : code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

使用用户 code 换取用户 access_token

有了用户 code,我们需要用这个临时 code,调用微信接口换为用户 的 access_token。

调用以下接口:

sh 复制代码
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 请求。

js 复制代码
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)
}

拉取用户信息

注意: 只有之前的 scopesnsapi_userinfo 时,这一步才能调通,否则没有权限。

调用以下接口:

sh 复制代码
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 英语

就可以拿到用户信息了。

代码示例:

最终可以拿到用户的个人信息了。

js 复制代码
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)
}