Loading... ## 1、账户申请 1.1 **打开微信开放平台: [https://open.weixin.qq.com/](https://open.weixin.qq.com/) 首先进行账号的注册** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200508174330576.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNzkxNw==,size_16,color_FFFFFF,t_70) 1.2 **开发者资质认证** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200508174351886.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNzkxNw==,size_16,color_FFFFFF,t_70) 1.3 **创建网站应用** ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200508174405949.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNzkxNw==,size_16,color_FFFFFF,t_70) **填写应用的相关信息** 应用通过审核后,会得到`AppID`和 `AppSecret`,后边进行编码中会使用。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200508174426788.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNzkxNw==,size_16,color_FFFFFF,t_70) ## 2、登录流程(Vue.js) 1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数; 2. 通过code参数加上AppID和AppSecret等,通过API换取access_token; 3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。 获取access_token时序图: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200508174446207.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzczNzkxNw==,size_16,color_FFFFFF,t_70) ### 步骤: > 说明: `domain`: 指的是域名或者IP地址 **1、添加一个div, 用于显示微信登陆二维码** ```html has-numbering <div id="weixin"></div> 1 ``` **2、添加mounted** ,引入微信登录二维码 JS ```javascript has-numbering mounted() { var obj = new WxLogin({ id: "weixin", appid: "wx3bdb1192c22883f3", scope: "snsapi_login", // 扫码成功后 跳转的地址 redirect_uri: "http://domain/weixinlogin" }); }, head: { script: [ { src: "http://res.wx.qq.com/connect/zh_CN/htmledition/js/wxLogin.js" } ] } 1234567891011121314 ``` * **appid** : 应用唯一标识 * **scope** :应用授权作用于 * **redirect_uri** :[回调](https://so.csdn.net/so/search?q=%E5%9B%9E%E8%B0%83&spm=1001.2101.3001.7020)地址,是微信登陆成功后要跳转到的页面 3、**显示二维码** 扫描二维码登录后,点击确认登录按钮后,浏览器会自动跳到: `http://domain/weixinlogin?code=02147Yff12Yhgz0ArCef1qabgf147Yf0&state=undefined` 这个**code** 是微信发给用户的**临时令牌** 。我们可以根据**code** 再次请求微信第三方登陆接口得到access_token(正式令牌) ## 3、获取access_token ### 3.1、API 介绍 > **通过code获取access_token** **1、接口说明** * **HTTP请求方式** : GET * **URL** :https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code **2、参数说明** | 参数 | 是否必须 | 说明 | | ------------ | ---------- | --------------------------------------------------------- | | appid | 是 | 应用唯一标识,在微信开放平台提交应用审核通过后获得 | | secret | 是 | 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得 | | code | 是 | 填写第一步获取的code参数 | | grant_type | 是 | 填authorization_code | **3、返回说明** ```json has-numbering { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE" } 1234567 ``` | 参数 | 说明 | | --------------- | ---------------------------------------------- | | access_token | 接口调用凭证 | | expires_in | access_token接口调用凭证超时时间,单位(秒) | | refresh_token | 用户刷新access_token | | openid | 授权用户唯一标识 | | scope | 用户授权的作用域,使用逗号(,)分隔 | ### 3.2、用Node.js创建服务 > 也可以用Java,Python 等其他语言 1. **新建文件 server.js** ```javascript has-numbering var http = require('http'); var https = require('https'); var url = require('url'); http.createServer(function(request,response){ var params=url.parse(request.url, true).query; // 通过审核后,得到的appid, AppSecret var appid='************'; var secret='*******************'; if(params.operation==='token'){ https.get( `https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${params.code}&grant_type=authorization_code`, function (res) { res.on('data', function (chunk) { response.writeHead(200,{'Content-Type':'application/json;charset=utf-8' ,"Access-Control-Allow-Origin": "*" }); response.end(chunk); }); }) } }).listen(8888); // 终端打印如下信息 console.log('Server running at http://127.0.0.1:8888/'); 123456789101112131415161718192021 ``` 2. **在控制台输入 `node server` 运行服务** 3. **访问地址** `http://localhost:8888/?code=02147Yff12Yhgz0ArCef1qabgf147Yf0&operation=token` 4. **得到结果** ```json has-numbering { "access_token": "10_zSHADX2JGMivKFfa4nMbZV3ECzY21UY3qrF5ADyjpr_iiLUifo-nlN0GaRnUEN9T7BagiwSC07awplRFIO1Ghw", "expires_in": 7200, "refresh_token": "10__zl8gcJz0RXVDKtksbNTQJZ2uK1HiLJZ3I5PcSkA2VB3b6WXi2CR3R_htW6B8kKOmj-91p08SJMfVKkL84vP1w", "openid": "oypcC1u9r-mxVsRGSLFqE65lysVI", "scope": "snsapi_login", "unionid": "o6JuL1gaIwnVsZC5BpRYImTHKTm8" } 12345678 ``` ### 3.3 前端页面调用node服务 1、**通过 axios 调用node服务,新建文件:@/api/weixin.js** > 这里是因为接口统一管理,单独存放在api文件下 > ```javascript has-numbering import axios from 'axios' export function getAccessToken(code) { return axios.get(`http://localhost:8888?operation=token&code=${code}`) } 1234 ``` **2、添加工具 utils/param.js (用于获取浏览器地址栏参数code)** ```javascript has-numbering export function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if(r != null) return unescape(r[2]); return null; } 123456 ``` **3、创建weixinLogin.vue** ```javascript has-numbering <template> <div></div> </template> <script> import { getUrlParam } from '@/utils/param' import { getAccessToken } from '@/api/weixin' export default { mounted(){ let code=getUrlParam('code') if(code!==null){//如果是微信登陆 //根据code获取access_token getAccessToken(code).then( res=>{ let access_token= res.data.access_token let openid= res.data.openid console.log('access_token:'+access_token+ 'openid:'+openid) }) } } } </script> 123456789101112131415161718192021 ``` ## 4、获取用户头像和昵称 ### 4.1、API **1、接口说明** * **HTTP请求方式** : GET * **URL** :`https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID` **2、参数说明** | 参数 | 是否必须 | 说明 | | -------------- | ---------- | ---------------------------------------------------------------- | | access_token | 是 | 调用凭证 | | openid | 是 | 普通用户的标识,对当前开发者帐号唯一 | | lang | 否 | 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN | **3、返回说明** ```json has-numbering { "openid":"OPENID", "nickname":"NICKNAME", "sex":1, "province":"PROVINCE", "city":"CITY", "country":"COUNTRY", "headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0", "privilege":[ "PRIVILEGE1", "PRIVILEGE2" ], "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL" } 1234567891011121314 ``` | 参数 | 说明 | | ------------ | -------------------------------------------------------------------------------------------------------------------------- | | openid | 普通用户的标识,对当前开发者帐号唯一 | | nickname | 普通用户昵称 | | sex | 普通用户性别,1为男性,2为女性 | | province | 普通用户个人资料填写的省份 | | city | 普通用户个人资料填写的城市 | | country | 国家,如中国为CN | | headimgurl | 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 | | privilege | 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) | | unionid | 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 | ### 4.2、添加 node 服务 **新增代码** ```javascript has-numbering if(params.operation==='userinfo'){ https.get(`https://api.weixin.qq.com/sns/userinfo?access_token=${params.access_token}&openid=${params.openid}`, function (res) { res.on('data', function (chunk) { // 发送响应数据 "Hello World" response.writeHead(200,{'Content-Type':'application/json;charset=utf-8' ,"Access-Control-Allow-Origin": "*" }); response.end(chunk); }); }) } 123456789 ``` **完整** ```javascript has-numbering var http = require('http'); var https = require('https'); var url = require('url'); http.createServer(function (request, response) { var params = url.parse(request.url, true).query; // 通过审核后,得到的appid, AppSecret var appid = '************'; var secret = '*******************'; if (params.operation === 'token') { https.get(`https://api.weixin.qq.com/sns/oauth2/access_token?appid=${appid}&secret=${secret}&code=${params.code}&grant_type=authorization_code`, function (res) { res.on('data', function (chunk) { response.writeHead(200, { 'Content-Type': 'application/json;charset=utf-8', "Access-Control-Allow-Origin": "*" }); response.end(chunk); }); }) } if (params.operation === 'userinfo') { https.get(`https://api.weixin.qq.com/sns/userinfo?access_token=${params.access_token}&openid=${params.openid}`, function (res) { res.on('data', function (chunk) { // 发送响应数据 "Hello World" response.writeHead(200, { 'Content-Type': 'application/json;charset=utf-8', "Access-Control-Allow-Origin": "*" }); response.end(chunk); }); }) } }).listen(8888); // 终端打印如下信息 console.log('Server running at http://127.0.0.1:8888/'); 12345678910111213141516171819202122232425262728 ``` ### 4.3、将用户信息保存到Token中 **1、安装 js-cookie** ```shell has-numbering npm install js-cookie --save 1 ``` **2、新建auth.js** ```javascript has-numbering import Cookies from 'js-cookie' const TokenKey = 'User-Token' const NameKey = 'User-Name' const AvatarKey = 'User-Avatar' export function setUser(token, name, avatar) { Cookies.set(NameKey, name) Cookies.set(AvatarKey, avatar) Cookies.set(TokenKey, token) } export function getUser() { let name = Cookies.get(NameKey) let avatar = Cookies.get(AvatarKey) let token = Cookies.get(TokenKey) let user = { name, avatar, token } return user } export function removeUser() { Cookies.remove(NameKey) Cookies.remove(AvatarKey) Cookies.remove(TokenKey) } 12345678910111213141516171819202122232425 ``` ### 4.4、修改weixin.js > 新增方法,用于根据access_token和openid获取用户信息 > ```javascript has-numbering import axios from 'axios' export function getAccessToken(code) { return axios.get(`http://localhost:8888?operation=token&code=${code}`) } export function getUserinfo(access_token,openid) { return axios.get(`http://localhost:8888?operation=userinfo&access_token=${access_token}&openid=${openid}`) } 12345678910 ``` **在获取access_token和openid后,再次请求接口,获取昵称和头像,保存到cookie中** ```js has-numbering <template> <div></div> </template> <script> import { getUrlParam } from '@/utils/param' import { getAccessToken } from '@/api/weixin' import { setUser } from '@/utils/auth' export default { mounted(){ let code=getUrlParam('code') if(code!==null){//如果是微信登陆 //根据code获取access_token getAccessToken(code).then( res=>{ let access_token= res.data.access_token let openid= res.data.openid weixin.getUserinfo( access_token, openid ).then( res => { //提取用户昵称和头像 let nickname= res.data.nickname let headimgurl= res.data.headimgurl // 将用户信息保存到token中 setUser(access_token,nickname,headimgurl) location.href='/' //跳转到首页 }) }) } } } </script> 1234567891011121314151617181920212223242526272829 ``` 这样页面就可以用getUser获取当前登录用户的用户名,头像 最后修改:2022 年 03 月 15 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏