微信公众号的配置和专业名词就不介绍了,不懂的问度娘,我就直接上代码 点击下载完整demo
先说一下我的demo放的位置:
微信H5授权登录分两种:
① 静默授权:snsapi_base,没有弹窗,只能获取用户的openId。
②非静默授权:snsapi_userinfo,有弹框弹出需要用户手动点击确认授权。可以获取openId,用户的头像、昵称等
下面是微信官方给的流程,大家大概了解一下就行。
1 第一步:用户同意授权,获取code
2 第二步:通过code换取网页授权access_token
3 第三步:刷新access_token(如果需要)
4 第四步:拉取用户信息(需scope为 snsapi_userinfo)
5 附:检验授权凭证(access_token)是否有效
下面是我的流程
1 在微信里打开一个页面判断是否登录(一般都是本地缓存保存token,比如setStorageSync)
2 如果没有登录,则需要通过当前url去获取code,但是此时肯定是获取不到的。
3 通过微信open.weixin.qq.com/connect/oauth2/authorize 转换一下就可以获取到,然后通过redirect_uri再跳回到步骤2中的url,
https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=' + encodeURIComponent('') + '&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect
4 此时步骤2中的url一定是有code的(不要为为什么,腾讯就是通过这种机制给你code让你获取的)
5 把获取到的code传给后端,经过后端和腾讯接口的对接,就成功获取到openid等用户信息,对接到你们自己的登录注册系统,然后返回登录token保存到本地。
上面是大致流程,下面我简单说一下代码:
在onload方法里调用
onLoad(){
this.token = uni.getStorageSync('token');
//判断是否登录
if(!unils.stringIsEmpty(this.token)){
console.log('已登录');
} else {
unils.isLoginAndwxLoginH5Login('/pages/clue/clue');
}
},
封装代码:
//有三个地方需要修改
//getWxCode 方法有两个地方 1 你的appid 2 你的前端地址
//getTokenByCode 方法里的 一个地方 你的接口地址
//判断字符串是否为空
const stringIsEmpty = function (obj){
if(typeof obj == "undefined" || obj == null || obj == ""){
return true;
}else{
return false;
}
}
const costomShowToast = function (title,duration=2000){
uni.showToast({
title:title,
duration:duration,
icon:'none',
})
}
/**
* 判断是否是在微信打开
*/
const isWechat = function() {
return String(navigator.userAgent.toLowerCase().match(/MicroMessenger/i)) === "micromessenger";
}
/**
* 获取url里的微信code值
* @param {Object} name
*/
const getUrlCode = function (name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null
}
/**
* 获取微信登录code
* @param {Object} redirect_path
*/
const getWxCode = function(redirect_path){
//console.log('33333');
//console.log(redirect_path);
if(this.isWechat()) {
// console.log('getWxCode22');
// 截取地址中的code,如果没有code就去微信授权,如果已经获取到code了就直接把code传给后台获取openId redirect_uri 是你的站点域名,一定要encodeURIComponent
let code = this.getUrlCode('code')
if (this.stringIsEmpty(code)) {
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=' + encodeURIComponent('https://www.xxxxx.com/h5'+redirect_path) + '&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect'
//redirect_uri地址里面不能多/,如果多一个/就会跳转不成功,所以redirect_path要注意是/pages/clue/cule
// redirect_uri是授权成功后,跳转的url地址,微信会帮我们跳转到该链接,并且通过?的形式拼接code,这里需要用encodeURIComponent对链接进行处理。
// 如果配置参数一一对应,那么此时已经通过回调地址刷新页面后,你就会再地址栏中看到code了。
// http://127.0.0.1/pages/views/profile/login/login?code=001BWV4J1lRzz00H4J1J1vRE4J1BWV4q&state=1
}
} else {
this.costomShowToast('请在微信客户端打开!');
}
}
/**
* 根据code获取登录token
* 原理:根据code获取微信openid,然后根据openid判断是否登录
* @param {Object} code
*/
const getTokenByCode = function(code){
return new Promise(function(resolve, reject) {
// console.log('getTokenByCode');
// console.log(code);
uni.request({
url: 'https://www.xxxx.com/gettokenbycode',//一定要改成你的接口地址
method:'GET',
data:{
'code':code,
},
success:(res)=>{
// console.log(res.data);
if(res.data.code != 1){
resolve(false);
} else {
uni.setStorageSync('token', res.data.data.userinfo.token);
resolve(true);
// this.costomShowToast('登录成功!');
}
},
fail:(res)=>{
resolve(false);
}
})
}).catch((e) => {
console.log(e)
});
}
/**
* 根据code获取登录,如果成功就跳转到对应的toUrl
* @param {Object} code 微信code
* @param {Object} toUrl 要跳转的地址
*/
const getTokenByCodeToUrl = function(code,toUrl){
var p = this.getTokenByCode(code);
p.then(function(loginResult){
//console.log("==============getTokenByCodeToUrl============"+toUrl);
if(loginResult){
uni.switchTab({//如果是pages.json中pages的第一个地址,则用navigateTo方法不好用,需要用switchTab方法
url:toUrl,//跳转的时候toUrl必须写成/pages/clue/clue前面一定要有/
})
window.location.reload();
} else {
console.log("getTokenByCodeToUrl登录失败!");
this.costomShowToast('登录失败!');
}
});
}
/**
* 对外方法,对外调用就这个就可以,判断微信H5登录并跳转到相应的地址toUrl
* @param {Object} toUrl 要跳转的地址
*/
const isLoginAndwxLoginH5Login = function (toUrl){
//获取微信code码
let code = this.getUrlCode('code');
//console.log('isLoginAndwxLoginH5Login');
//console.log(code);
if(!this.stringIsEmpty(code)) {
//console.log('3333333333333333isLoginAndwxLoginH5Login');
this.getTokenByCodeToUrl(code,toUrl);//跳转路径前面一定要加"/"
} else {
this.getWxCode(toUrl);
}
}
module.exports = {
stringIsEmpty,
isLoginAndwxLoginH5Login,
}