关于前端:10分钟带你完成微信网页授权获取用户信息搭建内网映射测试

39次阅读

共计 6108 个字符,预计需要花费 16 分钟才能阅读完成。

前言

大家平时在工作中,或多或少应该接触过微信鉴权登录,获取用户信息的相干需要。也有小伙伴常常会在群里问一些相干的问题,比方

  • 鉴权登录的整体流程是什么?
  • 整个流程外面,前端和后端的分工是什么?
  • 前端专门筹备了一个鉴权回调页面,要怎么回到鉴权前的页面?
  • 怎么在本地测试微信网页受权?

先看看微信官网的鉴权流程怎么形容的

第一步:用户批准受权,获取 code
第二步:通过 code 换取网页受权 access_token
第三步:刷新 access_token(如果须要)
第四步:拉取用户信息(需 scope 为 snsapi_userinfo)

还是懵,没关系,我在这里专门筹备了一个小🌰,来实现了一套简易版的网页受权 + 获取用户信息的性能,整个流程大略是这样的

在这个流程中,前端不必做太多事,只须要判断有没有用户信息,如果没有,剩下的事件交给服务端,等服务端全副解决实现,会带着用户信息,返回之前的页面。

并且前端无需筹备专门的受权后果页。

流程

第一步:内网映射

下载软件

下载地址:ngrok.com/download

解压进去之后是这个货色

终端启动

将解压进去的文件拖到终端中,紧接着写 http 3000,意思就是用 ngrok 在 3000 端口上开启一个 http 映射隧道。

启动之后呈现上面这个界面,就阐明胜利了。

这个就是咱们须要的域名:https://0772-183-159-254-252….

第二步:微信测试号

登录测试账号

登录地址:mp.weixin.qq.com/debug/cgi-b…

目前咱们拿到了 appID 和 appsecret,接口配置信息和 JS 接口平安域名先临时不必管,网页受权用不到。

批改受权回调域名

网页向下翻,翻到网页服务 => 网页账号 => 批改

将之前拿到的内网映射地址填进来,留神不要写 https://

扫码关注测试号
因为如果不关注,测试受权会报错的

第三步:搭建我的项目

这里咱们应用 express 这个 node 框架

package.json

{
  "name": "simple-wx-auth-by-express",
  "version": "1.0.0",
  "scripts": {"start": "node index.js"},
  "dependencies": {
    "axios": "^0.21.4",
    "express": "^4.17.1"
  },
  "devDependencies": {}}

index.js

留神将之前内网映射的地址、微信测试号的 appID 和 appsecret 填写到对应的地位;

const express = require('express');
const app = express();
const axios = require('axios');
const port = 3000; // 启动端口

const SERVICE_URL = 'https://0772-183-159-254-252.ngrok.io'; // 服务器地址,把内网映射的地址填写到这里
const appID = ''; // 微信测试号的 appid
const appsecret = ''; // 微信测试号的 appsecret

/**
 * @description 拼接残缺的受权地址
 * @param {string} webUrl 前端调用受权前的地址(受权完结后须要返回的地址)* @date: 2021/9/27
 */
const getAuthUrl = (webUrl) => {let redirectUri = encodeURIComponent(`${SERVICE_URL}/wxBack?webUrl=${webUrl}`);
    return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appID}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo#wechat_redirect`
}

/**
 * @description 获取 accessToken 和 openid
 * @param {string} code 受权失去的 code
 * @date: 2021/9/27
 */
const getAccessTokenByCode = async (code) => {let {data} = await axios.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appID}&secret=${appsecret}&code=${code}&grant_type=authorization_code`)
    return data
}

/**
 * @description 获取微信用户信息
 * @param {string} accessToken
 * @param {string} openid 用户 openid
 * @date: 2021/9/27
 */
const getUserInfo = async (accessToken, openid) => {let {data} = await axios.get(`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openid}&lang=zh_CN`)
    return data
}

// 前端页面
app.get('/user', (req, res) => res.sendFile(__dirname + "/" + "user.html"));

// 鉴权第一步:重定向至微信
app.get('/goAuth', (req, res) => {
    // 拿到调用受权的前端地址
    let {webUrl} = req.query;
    // 拿到鉴权的残缺地址
    let authUrl = getAuthUrl(webUrl);
    // 重定向
    res.redirect(authUrl);
})

// 鉴权第二步:微信重定向回服务
app.get('/wxBack', async (req, res) => {
    // 拿到 code 和调用受权的前端地址
    let {webUrl, code} = req.query;
    // 获取 accessToken
    let {access_token, openid} = await getAccessTokenByCode(code);
    // 获取用户信息
    let {nickname, headimgurl} = await getUserInfo(access_token, openid);
    // 重定向回前端
    headimgurl = headimgurl.replace('thirdwx.qlogo.cn', 'wx.qlogo.cn');
    res.redirect(`${webUrl}?openid=${openid}&nickname=${nickname}&headimgurl=${headimgurl}`);
})

app.listen(port, () => {console.log(`app listening at http://localhost:${port}`)
})



const express = require('express');
const app = express();
const axios = require('axios');
const port = 3000; // 启动端口

const SERVICE_URL = 'https://0772-183-159-254-252.ngrok.io'; // 服务器地址,把内网映射的地址填写到这里
const appID = ''; // 微信测试号的 appid
const appsecret = ''; // 微信测试号的 appsecret

/**
 * @description 拼接残缺的受权地址
 * @param {string} webUrl 前端调用受权前的地址(受权完结后须要返回的地址)* @date: 2021/9/27
 */
const getAuthUrl = (webUrl) => {let redirectUri = encodeURIComponent(`${SERVICE_URL}/wxBack?webUrl=${webUrl}`);
    return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appID}&redirect_uri=${redirectUri}&response_type=code&scope=snsapi_userinfo#wechat_redirect`
}

/**
 * @description 获取 accessToken 和 openid
 * @param {string} code 受权失去的 code
 * @date: 2021/9/27
 */
const getAccessTokenByCode = async (code) => {let {data} = await axios.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appID}&secret=${appsecret}&code=${code}&grant_type=authorization_code`)
    return data
}

/**
 * @description 获取微信用户信息
 * @param {string} accessToken
 * @param {string} openid 用户 openid
 * @date: 2021/9/27
 */
const getUserInfo = async (accessToken, openid) => {let {data} = await axios.get(`https://api.weixin.qq.com/sns/userinfo?access_token=${accessToken}&openid=${openid}&lang=zh_CN`)
    return data
}

// 前端页面
app.get('/user', (req, res) => res.sendFile(__dirname + "/" + "user.html"));

// 鉴权第一步:重定向至微信
app.get('/goAuth', (req, res) => {
    // 拿到调用受权的前端地址
    let {webUrl} = req.query;
    // 拿到鉴权的残缺地址
    let authUrl = getAuthUrl(webUrl);
    // 重定向
    res.redirect(authUrl);
})

// 鉴权第二步:微信重定向回服务
app.get('/wxBack', async (req, res) => {
    // 拿到 code 和调用受权的前端地址
    let {webUrl, code} = req.query;
    // 获取 accessToken
    let {access_token, openid} = await getAccessTokenByCode(code);
    // 获取用户信息
    let {nickname, headimgurl} = await getUserInfo(access_token, openid);
    // 重定向回前端
    headimgurl = headimgurl.replace('thirdwx.qlogo.cn', 'wx.qlogo.cn');
    res.redirect(`${webUrl}?openid=${openid}&nickname=${nickname}&headimgurl=${headimgurl}`);
})

app.listen(port, () => {console.log(`app listening at http://localhost:${port}`)
})

user.html

这是专门用来测试的页面,因为只须要测一下有没有拿到用户信息,所以仅仅简略的获取了一下 openid 和用户头像。

  • 先判断 url 上有没有携带 openid,如果没有,就间接重定向跳转到服务器地址开始受权;
  • 如果有,就间接把获取到的头像显示在页面上;
  • 留神:这里也须要把内网映射地址批改一下
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
</head>
<body>
<div id="app"></div>
<script>
    var SERVICE_BASE = 'https://0772-183-159-254-252.ngrok.io' // 内网映射的服务端地址
    // 获取 url 参数
    function getQueryVariable() {
        var url = location.search; // 获取 url 中 "?" 符后的字串
        var theRequest = new Object();
        if (url.indexOf("?") != -1) {var str = url.substr(1);
            strs = str.split("&");
            for (var i = 0; i < strs.length; i++) {theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
            }
        }
        return theRequest;
    }

    // 获取用户信息
    function getUserInfo() {var params = getQueryVariable();
        var openid = params.openid;
        if (!openid) { // 开始受权
            window.location.href = SERVICE_BASE + '/goAuth?webUrl=' + window.location.href;
        } else { // 受权完结
            let html = ` 头像:<img src="${params.headimgurl}">`
            let app = document.getElementById('app');
            app.innerHTML = html;
        }
    }

    window.addEventListener('load', function () {getUserInfo();
    })
</script>
</body>
</html>

第四步:测试

装置依赖

npm install

启动我的项目

npm run start

微信拜访页面

https://0772-183-159-254-252.ngrok.io/user

如果不出意外,拜访页面之后,你应该能弹出受权,批准之后回返回页面并呈现你的头像了。

这里因为我批准受权过,所以没有再次弹出来~

git 地址

地址:github.com/zhuyuqian/s…

结束语

本文提供作者:嘟小乾
原贴地址:https://juejin.cn/post/701248…
感觉文章写的好,请给戳↑链接关注作者,给文章点个赞嗷~

更多好文,请关注 公众号【推推猿】,退出 IT 人员社群,取得人脉拓展和大佬们面对面交换~ 更有大厂面试教训、内推岗位的一手材料同步获取~

正文完
 0