从头学习微信生态开发(二)-公众号授权

 0 1条评论

先看一下官方文档,写的还算清晰,当然实际开发中,还是会踩到不少坑的。

服务端是node+ts开发的,其他语言基本也是大同小异。前端是vue3.0。

第一步,去申请一个微信公众平台接口测试帐号

有了测试账号就方便很多,回调地址可以使用IP形式,不强迫使用域名,如果不用开发模式,那么还要本地做一个域名映射其实也挺麻烦,我个人选择测试账号。

然后添加一个网页授权获取用户基本信息,把本地的IP写上即可。


我这里填写的是192.168.1.4:7789,记住这里不要填写127.0.0.1这种本地IP,要通过ipconfig命令获取的本地的内网IP。

第二步,获取code

必须是让用户浏览器跳转到https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect这个页面,然后此页面再会跳转到redirect_uri指定的url,并且会携带code和state两个query参数。

注意:这里必须是页面跳转,前端跳转可以用js的location.href方法,后端跳转可以用res.redirect方法。

这里前端和后端跳转我都尝试过,后端跳转么,之后一系列的操作都是后端来执行,前端会轻松很多,以下一行代码搞定。

<a href="http://192.168.1.4:12159/wx/serverauth/member">提交本地</a>

但是有一个问题,最终后端还是要再跳转到前端的页面,那么此时如何把用户信息输送给前端,是一个麻烦事,不能直接通过query参数传递吧,那太不安全,可能还要通过各种加密解密来实现了。

我这里也贴一下,后端跳转代码,也非常简单,也就是上面serverauth/member这个url会跳转到以下后端地址

/**
 * 请求snsapi_userinfo作用域的路由
 */
 const routerGetMember = async (req, res) => {
    const callback = encodeURIComponent(`http://191.168.1.4/wx/serverauth/callbackbase`)
    const url = `https://open.weixin.qq.com/connect/oauth2/authorize?
        appid=${global.CONFIG.WX.AppID}&redirect_uri=
        ${callback}&response_type=code
        &scope=snsapi_userinfo&state=STATE#wechat_redirect`
    res.redirect(url)
}

我最终使用的还是前端跳转,代码如下,button添加事件。

<button @click='authUserInfo'>获取授权</button>

ts代码如下

const callback = 'http://192.168.1.4:7789/wx/exam'
const authUserInfo = () => {
    const url = `https://open.weixin.qq.com/connect/oauth2/authorize?
    appid=APPID&redirect_uri=${callback}&response_type=code
    &scope=snsapi_userinfo&state=STATE#wechat_redirect`
    location.href = url
}

这里不用担心appid泄露的问题,这本身就不是敏感信息,就好比用户名一样,这里请求微信服务器后,会再跳转到本身的页面,callback就是当前页面的路由。一旦页面跳转后,微信就会弹出一个请求用户授权窗口,用户同意后,就会跳回redirect_uri里的url。

之后在onMounted方法中判断,url中是否有code参数,有的话则发送请求到后端,有后端返回用户信息。

onMounted(async () => {
    if (route.query.code) {
    const result = await AJRequest(route.query.code as string)
    // 获得用户数据,距离逻辑后端实现
    console.log(result)
    }
})

AJRequest方法如下

/**
 * 
 * @param code 请求token的code
 * @returns 
 */
export const AJReques = (code: string => {
    return ajax<TUserInfoMember>({
        method: 'POST',
        url: '/wx/clientauth/memberuserinfo',
        data: { code }
    })
}

/wx/clientauth/memberuserinfo是后端实现的方法,下方会讲。

第三步,后端获取access_token

定义一个函数,后端获取到code后,发送使用axios发送post请求获取access_token

/**
 * 根据code请求用户token结果
 * @param code redirect_uri页面中query中的参数code
 * @returns 
 */
export const fnRequesToken = async (code: string) => {
    const tokenURL = `https://api.weixin.qq.com/sns/oauth2/access_token?a
    ppid=${APPID}&secret=${AppSecret}
    &code=${code}
    &grant_type=authorization_code`
    const tokenInfo = await axios.post(tokenURL)
    return tokenInfo.data as ITokenUserInfo
}

第四步,通过access_token获取用户信息

第二步中,请求后端的地址,是一个node路由,先要通过code获取的access_token,代码如下:

/**
 * snsapi_userinfo作用域获取的code,
 * @param req 
 * @param res 
 * @param next 
 */
const getMemberUserInfo = async (req, res) => {
    try {
        const code = req.body.code
        const { access_token, openid} = await fnRequestToken(code as string)
        const userURL = `https://api.weixin.qq.com/sns/userinfo
            ?access_token=${access_token}
            &openid=${openid}&lang=zh_CN`
        const wxUser: IWXUserInfo = (await axios.post(userURL)).data
        // wxUser就是微信用户对象了
        // 实际业务中会根据情况进行数据库操作
        res.send(wxUser)
    }
    catch (e) {
        return res.send(e)
    }
}

大致的流程就是如此,实际开发中,需要根据需求灵活变通,以上只是最基本的实现逻辑。

下一节我讲讲,如何通过请求snsapi_base作用域,让用户无感授权,避免每次用户授权都要弹出窗口,非常不友好。

下一篇:从头学习微信生态开发(三)-无感授权base作用域

本文作者:双黑

版权声明:本站文章欢迎链接分享,禁止全文转载!

游客