之前在《应用商店上架记》一文中写过,关于三方登录中的微信账号登录不针对个人开发者开放的问题。就在这几天搜索了一下个人开发者微信登录的问题,有人提出了可以使用小程序的登录来实现微信登录。思考了一下,按照这个逻辑应该是可行的。因为小程序本身已经具备微信登录的相关能力,并且之前小程序也上架了。
现在需要解决的问题就剩下这么几个:
1.在微信小程序实现微信登录相关功能 2.从 app 直接调用小程序登录页面,获取 openid或者登录凭证 3.将小程序获取的 opendi 或者登录凭证调期 app,将相关的凭证回传 app 之后,app 使用相关的凭证进行登录。
有了思路之后,后面就一步一步来实现吧:
一、小程序登录
1.获取小程序 appid,登录微信公众平台,官网链接:https://mp.weixin.qq.com/ 。点击开发管理页面查看小程序 appid
2.在 hbuilder 中修改 manifest.json 配置,微信小程序配置页面,填入微信小程序 appid
3.获取微信用户信息,可以使用uni.getUserProfile请求用户授权获取用户信息。接口文档地址:https://uniapp.dcloud.net.cn/api/plugins/login.html#getuserprofile
接口返回数据: 参数 类型 说明 userInfo OBJECT 用户信息对象 rawData String 不包括敏感信息的原始数据字符串,用于计算签名。 signature String 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息。 encryptedData String 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法。 iv String 加密算法的初始向量,详细见加密数据解密算法。 cloudID String 敏感数据对应的云 ID,开通云开发的小程序才会返回,可通过云调用直接获取开放数据,详细见云调用直接获取开放数据 errMsg String 描述信息
不过调用该接口返回的数据,并没有太多的实际价值,多数数据都是空的。
4.在能够获取基础数据之后,后续调用登录登录接口才能拿到凭证信息。
使用uni.login方法,provider参数输入’weixin’,成功的返回值中如果errMsg=“login:ok” 代表成功,
微信小程序端会返回一个code字符串
5.拿到 code 之后通过服务端代码换取 openid 文档地址: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
前端完整代码如下:
vue部分:
<!-- #ifdef APP-PLUS||MP --> <view class="fh-wechat-login-main"> <slot> <view class="fh-wechat-login-button" @click="dowechatLogin"> <view class="fh-wechat-icon"></view> 使用微信账号登录 </view> </slot> </view> <!-- #endif -->
js 部分:
dowechatLogin() { // 展示加载框 uni.showLoading({ title: '加载中', }); let url = this.$baseUrl + 'api/third-login/wechat-login/'; uni.getUserProfile({ desc: '登录后可同步数据', success: async (obj) => { console.log('obj', obj); // 调用 action ,请求登录接口 // await this.login(obj); uni.login({ provider: 'weixin', success: (res) => { console.log('res-login', res); this.code = res.code; console.log('code', res.code); if (res.errMsg == 'login:ok') { uni.request({ url: url, data: { code: this.code }, method: "POST", header: {}, success: (res) => { // console.log(res.data); }, fail: (e) => { console.log('failed:', e); uni.showToast({ title: '登录失败,请稍候再试', icon: 'none' }); this.isLoginProcess = false; } }); console.log('res', res); } }, }); }, fail: err => { console.log(err) uni.showToast({ title: '授权已取消', icon: 'error', mask: true, }); }, complete: () => { // 隐藏loading uni.hideLoading(); }, }); },
服务端部分:
def wechat_login(self, request): try: # user = request.user # user = User.objects.get(pk=1) try: code = request.data['code'] resp = requests.get( 'https://api.weixin.qq.com/sns/jscode2session?appid=appid&secret=secrct&js_code=' + code + '&grant_type=authorization_code ') resp_json = json.loads(resp.text) if 'errcode' in resp_json: return ErrorResponse(_('code 已经被使用')) # return DetailResponse(resp_json) # print(resp_json) user_info = resp_json # print(user_info) open_id = user_info['openid'] # auth_realname = user_info['auth_realname'] # 创建用户账号逻辑省略 msg = {'token': token.key, 'user': {} } return DetailResponse(msg) except Exception as e: print("Exception=", e) return ErrorResponse(_('数据错误')) except: return ErrorResponse(_('错误的数据格式'))
至此,小程序登录部分就算完成了。后端拿到授权获取的 code 之后通过接口换出 openid,基于 openid 进行账号创建。并且将账号信息返回小程序,实现登录功能。
二、app 打开小程序并且调起登录授权页面
1. 配置 uniapp 的微信分享功能
此处填写的 appid 跟上面的小程序的 appid 是一样的。
配置完成之后,在调试的时候需要重新进行自定义基座打包,并且运行的时候选择自定义基座。否则会提示打包不包含 share 模块。
2. app 打开小程序,相关代码:
appToMp() { let that = this let url = '/pages/page/wechatLogin' //跳转小程序的路径 plus.share.getServices(function(res) { var sweixin = null; for (var i = 0; i < res.length; i++) { var t = res[i]; if (t.id == 'weixin') { sweixin = t; } } if (sweixin) { that.wxPay = true sweixin.launchMiniProgram({ id: 'gh_8**********', //这里写你的小程序原始id(以gh开头) type: 0, //微信小程序版本类型可取值: 0-正式版; 1-测试版; 2-体验版。 默认值为0。 path: url, success(res) { // return true console.log('success=', res); }, fail(res) { uni.showToast({ title: '跳转小程序失败', icon: 'none', duration: 3000 }) console.log('跳转小程序失败', res) return false; }, }) } }, function(err) { console.log(JSON.stringify(err)); }) },
需要注意的是launchMiniProgram方法中的 id 为小程序原始 id,gh 开头的 id,如下图,小程序账号信息页面查看:
3. 登录微信开放平台,地址:https://open.weixin.qq.com/ 创建 app 并且提交审核。
在 ios 应用部分配置Universal Links,如下图:
4. 创建apple-app-site-association文件,并且上传到Universal Links根目录下,要求必须为 https。
文件内容如下:
{ "applinks": { "apps": [], "details": [ { "appID": "appTeamID.bundleid", "paths": ["/uni-universallinks/*"] } ] } }
appID为 teamid+ bundleid 的组合。具体可以登录苹果开发者后台查看
例如 teamid 为 abcdef,则 appID 为,abcdef.my.dayi.app
5. 同时需要启用上图中的Associated Domains,在 uniapp 项目中配置Associated Domains。打包时需要下载最新的 mobileprovison 文件进行打包测试。
6. 在微信开放平台绑定小程序,点击绑定小程序按钮输入小程序的账号密码进行绑定。
上述流程如果配置出现问题可能会出现下面的错误提示
此时就只能根据微信的文档进行排查了:https://docs.msdk.qq.com/v5/zh-CN/FAQS/402d19e50fff44c827a4f3b608bd5812/11796f3fcca548e16afca803e76e5265.html
到这里第二步就算完成了,剩下的第三步就简单了。
三、获取授权凭证跳会 app 进行自动登录
1. 小程序内创建授权登录页面,在这个页面需要能够获取 code 之后,并且回传到 app 内。跳转 app 需要使用独立的button 进行操作:
vue 代码:
<view v-if="isSuccess===0" class="fh-wechat-login-main" > <slot> <view class="fh-wechat-login-button" @click="LoginForWechat"> <view class="fh-wechat-icon"></view> 使用微信账号登录 </view> </slot> </view> <view v-if="isSuccess===1"> <button class="fh-wechat-login-main" open-type="launchApp" :app-parameter="params" @error="openError" style="font-size: 14px;">授权成功,点击返回APP登录</button> </view>
isSuccess用于控制获取到 code 之后显示返回 app 按钮。
js 代码:
uni.getUserProfile({ desc: '登录后可同步数据', success: async (obj) => { console.log('obj', obj); // 调用 action ,请求登录接口 // await this.login(obj); uni.login({ provider: 'weixin', success: (res) => { console.log('res-login', res); this.code = res.code; console.log('code', res.code); if (res.errMsg == 'login:ok') { this.params = 'code=' + this.code; console.log('res', res); this.isSuccess = 1; } }, }); }, fail: err => { console.log(err) uni.showToast({ title: '授权已取消', icon: 'error', mask: true, }); }, complete: () => { // 隐藏loading uni.hideLoading(); }, });
通过params进行参数传递
2. app 获取小程序回传的code 凭证进行登录操作
js 代码:
onShow() { // #ifdef APP-PLUS setTimeout(() => { console.log('wechat login call back') let code = plus.runtime.arguments if (code && code.toString().indexOf('code=')>=0) { plus.runtime.arguments = '' // ... console.log('code=', code); code = code.replace('code=', ''); if (code.length > 4) { //使用 code 进行登录操作 this.httpLoginwechatWithCode(code); } } }, 10) // #endif },
至此,整个微信账号登录的流程就算完成了,实际效果:
参考链接:
https://codeantenna.com/a/j7qBaSRtQd
https://blog.51cto.com/gblfy/5670283
https://docs.msdk.qq.com/v5/zh-CN/FAQS/402d19e50fff44c827a4f3b608bd5812/11796f3fcca548e16afca803e76e5265.html
28 comments
个人开发者和狗不得入内……
很准确了。😂
你这个方法现在有人用吗,一旦用的人多了,微信就会….
这个登录是小程序的正常功能,并没有用一些不被允许的方法。所有的功能都是正常调用的,不存在使用私有 api 之类的。
只要没碰到滥用的就没事,好多开发者会滥用权限,然后查到授权到个人开发者app了,就有可能收回权限,应该不至于,一个登陆还不算什么隐私功能,只是有这种可能。
现在个人开发者本来就没有微信登录的权限,所以还回收啥呢?难道小程序也不让用微信账号登录了?
这个登录连账号基础信息都拿不到,昵称,性别,用户名都是空的。意思是微信啥信息都没给,最后用 code 换了个 openid 用来登录,已经够寒酸了。
授权获取手机号是收费的,我也不需要手机号。所以,已经这么磕碜的功能了,也没什么好回收的了吧?😂
唯一有用的就是那个 openid,如果这个也不给了,那就哪天再把微信登录给关了呗。
授权获取手机号收费了?几年前还不收费来着,好久没碰过微信小程序了
看了演示,感觉还挺丝滑的
是哒 一次三分钱
https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/getRealtimePhoneNumber
1.未认证无法使用微信登录
2.认证需要企业资质
做大做强
主打一个瞎折腾~~
注册个公司吧,干起事来方便
每年维护也是个问题。这个等后期看看情况,不过也想过这个办法
看视频效果不错哦!
评论区里一群大老爷们围观一款女性产品,怪有意思的
不明觉厉!手机图标和红点消息密集症恐惧者 最后一个图片添加闺蜜的提示文字有错别字。
酱紫,没注意呢 找时间改改
惭愧啊,只能看懂第一张图片
不要在意这些细节,嘻嘻
就相当于,你的用户管理系统,交给了微信呗?
也不是这个意思,🍳来说所有的第三方登录本质上是做账号关联,账号系统还是自己管理。不管是微信还是 qq 都是通过授权登录换取 openid,在自己的账号系统内通过 openid 进行账号关联。
做这个的主要用处是简化用户注册登录流程。
姐姐太强了
融汇变通,嘎嘎
还有啊,你的博客发不了评论了一直失败呢。想问你漫画风用的哪个模型来着。
个人开发者在一些方面举步维艰呀,只能弯道通行了。
曲线救国,也算是个解决方案吧。毕竟国内用微信的用户群体还是非常大的,有了微信登录会方便很多。
实际测试无法登陆,不知道是不是微信版本低的缘故
什么表现?授权成功跳转回app没登陆吗?重启下app试试