uniapp+nodejs实现小程序登录流程,获取openID,附uniapp请求封装

小程序授权,拿到code向后台nodejs 发送请求交互过程

前端代码(uniapp)

<template>
	<view class="login">
		<view v-if="isCanUse">
			<view>
				<view class="header"><image src="../../static/icon/news-active.png"></image></view>
				<view class="content">
					<view>申请获取以下权限</view>
					<text>获得你的公开信息(昵称,头像、地区等)</text>
				</view>
				<button class="bottom" type="primary" open-type="getUserInfo" withCredentials="true" lang="zh_CN" @getuserinfo="wxGetUserInfo">授权登录</button>
			</view>
		</view>
		<u-toast ref="uToast" />
	</view>
</template>
<script>
export default {
    
    
	name: 'login',
	data() {
    
    
		return {
    
    
			SessionKey: '',
			OpenId: '', 
			nickName: null,
			avatarUrl: null,
			isCanUse: uni.getStorageSync('isCanUse') || true //默认为true
		};
	},
	async onLoad() {
    
    
		//默认加载
		await this.login();
		this.isCanUse = uni.getStorageSync('isCanUse');
	},
	methods: {
    
    
		//第一授权获取用户信息===》按钮触发
		wxGetUserInfo() {
    
    
			let _this = this;
			uni.getUserInfo({
    
    
			   //加下面lang:"zh_CN",返回才是中文
			    lang:"zh_CN",
				provider: 'weixin',
				success: function(infoRes) {
    
    
					uni.setStorageSync('isCanUse', false); //记录是否第一次授权  false:表示不是第一次授权
					_this.userLogin(infoRes.userInfo);
				},
				fail(res) {
    
    
					uni.showToast({
    
     title: '微信登录授权失败', icon: 'none' });
				}
			});
		},
		//登录
		login() {
    
    
			let _this = this;
			wx.getSetting({
    
    
				success: function(res) {
    
    
					if (res.authSetting['scope.userInfo']) {
    
    
						console.log('用户授权了');

						uni.showLoading({
    
    
							title: '登录中...'
						});
						uni.setStorageSync('isCanUse', false); //记录是否第一次授权  false:表示不是第一次授权
						_this.userLogin();
					} else {
    
    
						//用户没有授权
						console.log('用户没有授权');
						_this.isCanUse = true;
					}
				}
			});
		},
		userLogin(data) {
    
    
			let _this = this;
			// 1.wx获取登录用户code
			uni.login({
    
    
				provider: 'weixin',
				success: function(loginRes) {
    
    
					let code = loginRes.code;
					// console.log( loginRes)
					//2.将用户登录code传递到后台置换用户SessionKey、OpenId等信息
					// _this.getOpenId({ code });
					uni.hideLoading();
					//_this.$api.getOpenId是我接口的封装
					_this.$api.getOpenId({
    
     code }).then(res => {
    
    
						console.log(res)
						uni.hideLoading();
						if (!data) {
    
    
							// 获取用户信息
							uni.getUserInfo({
    
    
							    lang:"zh_CN",
								provider: 'weixin',
								success: function(infoRes) {
    
    
									//获取用户信息后向调用信息更新方法
									console.log(infoRes)
									// _this.updateUserInfo(infoRes.userInfo, res); //调用更新信息方法
								}
							});
						} else {
    
    
							_this.updateUserInfo(data, res); //调用更新信息方法
						}
					});
				}
			});
		},
	},
};
</script>
<style scoped lang="scss">
.header {
    
    
	margin: 90upx 0 90upx 50upx;
	border-bottom: 1px solid #ccc;
	text-align: center;
	width: 650upx;
	height: 300upx;
	line-height: 450upx;
}
.header image {
    
    
	width: 200upx;
	height: 200upx;
}
.content {
    
    
	margin-left: 50upx;
	margin-bottom: 90upx;
}
.content text {
    
    
	display: block;
	color: #9d9d9d;
	margin-top: 40upx;
}
.bottom {
    
    
	border-radius: 80upx;
	margin: 70upx 50upx;
	font-size: 35upx;
}
</style>

后台代码(nodeJS)路由文件

module.exports = (app) => {
    
    
  const express = require("express");
  const router = express.Router();
  let openid, sessionKey;
  router.post("/get_openid", async (req, res) => {
    
    
    let code = req.body.params.code; //获取小程序传来的code
    // let encryptedData = params.encryptedData;//获取小程序传来的encryptedData
    // let iv = params.iv;//获取小程序传来的iv( iv 是加密算法的初始向量)  uni.getUserInfo获取
    let appid = "自己的"; //自己小程序后台管理的appid,可登录小程序后台查看
    let secret = "自己的"; //小程序后台管理的secret,可登录小程序后台查看
    let grant_type = "authorization_code"; // 授权(必填)默认值
    let url =
      "https://api.weixin.qq.com/sns/jscode2session?grant_type=" +
      grant_type +
      "&appid=" +
      appid +
      "&secret=" +
      secret +
      "&js_code=" +
      code;
    let openid, sessionKey;
    let https = require("https");
    https.get(url, (res1) => {
    
    
      res1
        .on("data", (d) => {
    
    
          console.log("返回的信息: ", JSON.parse(d));
          openid = JSON.parse(d).openid; //得到openid
          sessionKey = JSON.parse(d).session_key; //得到session_key
          
          let data = {
    
    
            openid: openid,
            sessionKey: sessionKey,
          };
          //返回前端
          res.send(data);
        })
        .on("error", (e) => {
    
    
          console.error(e);
        });
    });
  });
    app.use("/user/api", router);
};

赠接口封装
文件目录
在这里插入图片描述
config.js

const BASE_URL = 'http://localhost:3000'
// import regeneratorRuntime from 'regenerator-runtime'
const showToast = (title) => {
    
    
    uni.showToast({
    
    
        title: title,
        icon: 'none'
    })
}
/**请求接口
 * @method http
 * @param {String} url 接口地址
 * @param {Object} data 接口参数
 * @param {Object} option 接口配置信息,可选
 * @return {Object} Promise
 */
const api = (url, data = {
    
    }, option = {
    
    }) => {
    
    
    let hideLoading = option.hideLoading || true // 是否显示 loading
    let hideMsg = option.hideMsg || true // 是否隐藏错误提示
    let token = '' // 登录鉴权获得的 token
    uni.getStorage({
    
    
        key: 'token',
        success: (ress) => {
    
    
            token = ress.data
        }
    })
    if (!hideLoading) {
    
    
        uni.showLoading({
    
    
            title: '加载中...',
            mask: true
        })
    }
    return new Promise((resolve, reject) => {
    
    
        uni.request({
    
    
            url: BASE_URL + url,
            method: option.method || 'POST', // 默认 post 请求
            header: {
    
    
                'Token': token
            },
            data: data,
            success: res => {
    
     // 服务器成功返回的回调函数
                if (!hideLoading) uni.hideLoading()
                if (res.statusCode === 200) {
    
    
					// console.log(res.data)
                    let result = res.data
					// console.log(result,2)
					  resolve(result)
                    if (result.errcode === '0') {
    
    
                        resolve(result)
                        return
                    }
                    // reject(result.errmsg)
                    if (!hideMsg) showToast(result.errmsg)
                } else {
    
     // 返回值非 200,强制显示提示信息
                    showToast('[' + res.statusCode + '] 系统处理失败')
                    reject('[' + res.statusCode + '] 系统处理失败')
                }
            },
            fail: (err) => {
    
     // 接口调用失败的回调函数
                if (!hideLoading) uni.hideLoading()
                if (err.errMsg != 'request:fail abort') {
    
    
                    showToast('连接超时,请检查您的网络。')
                    reject('连接超时,请检查您的网络。')
                }
            }
        })
    })
}
export default api

data.js

import api from '@/api/config.js'
let Api = {
    
    
	// 登录
	getOpenId(params) {
    
    
		return api('/user/api/get_openid', {
    
    params}, {
    
    method: 'POST'});
	},
};
export default Api;

main.js

import Vue from 'vue'
import App from '@/App'
import api from '@/api/data.js'
Vue.prototype.$api =api;
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
    
    
    ...App
})
app.$mount()

页面调用

//方法内
this.$api.getOpenId(params).then(res => {
    
    
	console.log(res)
});
或者
 async getOpenId() {
    
    
	let res=await this.$api.getOpenId(params)
	 console.log(res);
  },

猜你喜欢

转载自blog.csdn.net/weixin_46476460/article/details/111576199