背景
微信登陆作为比较常用的第三方登陆,实际应用比较多,比如小程序,微信公众号必不可少缺少 但是发现有一些初级人员还是不容易理解这当中的一个思路,故分享下当前微信登录的一个实现原理以及实战代码
原理
基本步骤 :
-
客户端判断token是否存在,token不存在则请求后端获取微信登陆地址
-
服务器返回相关的微信登陆地址(这个地方其实也可以由前端自己拼接 具体看自己情况 )
-
前端将获取到的微信地址(或者自己前端写好的地址也可以)做跳转
-
用户进行微信公众号确认(或者扫码登陆)此时会跳转到微信的地址。
-
微信则会返回到之前设置的回调登录地址上做处理(该回调地址为微信请求地址上带的redirect_uri)
-
服务器端验证信息的真实性以后将该用户的信息生成对应的token 通过做跳转到前端指定的页面比如 login/token/123
-
前端通过login/token/123 获取到对应的token信息 并保存在本地缓存,接下来请求接口带着这个token即可
具体流程图如下
实现
前端VUE部分
在路由里面做判断是否有token(判断是否登录操作) 没有则跳转到login页面
/src/view/Login.vue
created() {
try {
document.title = "登陆中...";
let ua = window.navigator.userAgent.toLowerCase();
if (ua.match(/MicroMessenger/i) == "micromessenger") {
this.$axios.get("/api/weixin/get_weixin_login_url", []).then((res) => {
//alert("跳转到微信授权页面", res.data.url);
window.location.href = res.data.url;
});
} else {
this.cli = true;
}
} catch (e) {
}
}
同时也检测是否在login 下面是否有token给到前端(登录成功部分操做)
/src/router/index.js
router.beforeEach((to, from, next) => {
var params = to.fullPath.split('/');
var token = localStorage.getItem('token');
//alert(to.fullPath);
//如果token不存在就跳转登录
if (!token && params[1] !== "login") {
//alert('如果token不存在就跳转登录', to.fullPath);
localStorage.setItem("beforeUrl", to.fullPath);
next("/login");
return false;
}
//保存用户的token信息
//并跳转到之前的地址
if (params[1] == "login" && params[2] == 'token') {
localStorage.setItem('token', params[3]);
var url = localStorage.getItem("beforeUrl");
//alert(url);
var urlParam = "/";
if (url) {
urlParam = url.split('/');
}
if (url == '' || url == null || urlParam[1] == "login") {
url = '/';
}
next(url);
return false;
}
next();
});
后端代码
获取微信登陆页面地址
$redirect_uri = urlencode("http://" .你的域名 . "/api/weixin/callback");
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $appId . "&redirect_uri=" . $redirect_uri . "&response_type=code&scope=snsapi_userinfo&state=STATE";
return json(['code' => 200, 'msg' => 'success', 'data' => ['url' => $url]]);
微信回调返回
//当前使用的为easywechat
$app = new Application(self::get_weixin_config());
$oauth = $app->oauth;
// 获取 OAuth 授权结果用户信息
$user = $oauth->user();
$info = Db::name('vote_user')->where('wx_id',$user['original']['openid'])->find();
if(empty($info)){
$add = [
'wx_id' => $user['original']['openid'],
'avatar' => $user['avatar'],
'name' => $user['name'],
'nickname' => $user['nickname'],
'wx_content' => json_encode($user),
'createtime' => time(),
'updatetime' => time(),
];
Db::name('vote_user')->insert($add);
$info = Db::name('user')->where('wx_id',$user['original']['openid'])->find();
}
$token = sha1($info['name'].$info['wx_id'].$info['updatetime']);
header('location:'. '/#login/token/'.$token); // 跳转到 user/profile
到此整个微信登陆流程结束