分类 编程技术 下的文章

微信小程序登录中另一种思路

背景

最近在做一个小程序,里面当然有登录功能。小程序的账号和后台管理系统中的账号是有关系的,只有在后台管理系统中录入的、状态正常的账号,小程序端对应的账号才有某些数据操作权限,小程序端和后台管理端的账号是通过手机号码进行匹配的。

方案

当用户首次打开小程序时,会有一个获取用户手机号码的button

<button open-type="getPhoneNumber" @getphonenumber='getPhoneNumber' withCredentials="true" lang="zh_CN">微信快捷登录</button>

getPhoneNumber回调中,可以获取到codeencryptedDataiv三个数据。

先使用wx.checkSession方法看下当前微信的登录状态:

  1. 如果没有登录,那么调用wx.login方法进行登录,也会获取到一个code,注意这个code和上面通过getPhoneNumber获取到的code是不一样的。将wx.login获取到的codeencryptedData以及iv这三个参数传递到后台进行处理。
    后台首先通过code调用微信接口获取到session信息,从session信息中可以获取到session_keyopenidunionid三个数据,然后根据session_keyencryptedData以及iv可以解密出手机号码。
    最后,可以保存openid等信息,根据手机号码匹配进行登录操作,下发token等。
  2. 如果微信登录状态是登录中,那么直接将 getPhoneNumber获取到的code传给后台,后台通过phonenumber.getPhoneNumber这个微信提供的接口直接获取到手机号码,从而进行后续操作(重新下发token、续签token等)。

其实,在微信小程序的登录中,最关键的就是小程序的登录态如何同业务本身的登录态进行统一。至少现在小程序的登录态不知道持续多久,并且也无法主动登出。所以只能通过另外的手段来进行登录态的控制。
这里采用的就是手机号码这个数据,这个手机号码可以在不调用wx.login接口的情况下使用,也就是说是独立的,和小程序登录状态无关的,那么我们就可以使用这个手机号进行相关token的处理。
甚至如果你不需要用户openid的话,甚至连wx.login这个接口都可以不理,根本无需关注微信的登录状态,就以我们通过手机号码获得的token为准即可。

fluter 2.0 刚刚发布,其中对Desktop的应用程序支持更加完善,虽然现在仍然任务是“beta snapshot”。

我就早早下载了flutter 2.0的sdk,用Microsoft Visual Code编写,将官方的默认的例子跑了起来。

1、到官网下载sdk,注意使用国内的官网,速度会快很多,按照教程进行安装,官网链接:https://flutter.cn/docs/get-started/install。注意,国内下载的sdk里面引用的repo地址依然是国外的,想提高下载速度,需要设定:

setx PUB_HOSTED_URL "https://pub.flutter-io.cn"
setx FLUTTER_STORAGE_BASE_URL "https://storage.flutter-io.cn"

2、安装完sdk,配置下vs code,安装flutter的插件

3、按照官网的流程,创建项目,带有的默认例子是一个counting的例子

4、默认的flutter项目是不支持desktop的,需要设定,

flutter config --enable-windows-desktop

5、这样在vs code中,就可以编译成windows的应用程序了。打包后包括一个exe文件、一个flutter_windows.dll,还有一个data,这些必须在同一个目录下。

6、程序分发的时候,当然可以将这些文件压缩打包,然后再解压缩执行。

7、如果想使用installer这种安装工具进行安装,支持window的HKEY、卸载等功能,那么就需要进行打包,推荐使用NSIS这个免费强大的工具,链接:https://nsis.sourceforge.io/Main_Page

附上我写的打包脚本:

; The name of the installer
Name "demo_install"

; The file to write
OutFile "demo_install.exe"

; Request application privileges for Windows Vista
RequestExecutionLevel user

; Build Unicode installer
Unicode True

; The default installation directory
InstallDir $PROGRAMFILES\demo_install

;--------------------------------

ShowInstDetails show

; Pages

Page directory
Page instfiles

UninstPage uninstConfirm
UninstPage instfiles

RequestExecutionLevel admin

;--------------------------------

; The stuff to install
Section "" ;No components page, name is not important

  ; Set output path to the installation directory.
  SetOutPath $INSTDIR
  
  ; Put file there
  ;RegDLL $INSTDIR/flutter_windows.dll
  File flutter_windows.dll
  File flutter_application_1.exe
  File /r data
  Rename $INSTDIR\flutter_application_1.exe demo_install.exe
  WriteUninstaller "$INSTDIR\uninstall.exe"
  
SectionEnd ; end the section

; Optional section (can be disabled by the user)
Section "Start Menu Shortcuts"

  CreateDirectory "$SMPROGRAMS\demo_install"
  CreateShortcut "$SMPROGRAMS\demo_install\Uninstall.lnk" "$INSTDIR\uninstall.exe"
  CreateShortcut "$SMPROGRAMS\demo_install\demo_install.lnk" "$INSTDIR\demo_install.exe"

SectionEnd

;--------------------------------

; Uninstaller

Section "Uninstall"
  
  ; Remove registry keys
  DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Example2"
  DeleteRegKey HKLM SOFTWARE\NSIS_Example2

  ; Remove files and uninstaller
  Delete $INSTDIR\example2.nsi
  Delete $INSTDIR\uninstall.exe
  Delete $INSTDIR\*
  ; Remove shortcuts, if any
  Delete "$SMPROGRAMS\demo_install\*.lnk"

  ; Remove directories
  RMDir /r "$SMPROGRAMS\demo_install"
  RMDir /r "$INSTDIR\data"
  RMDir /r "$INSTDIR"

SectionEnd

上文说了不要自己造轮子,要使用别人的轮子,这一文就说下使用别人的轮子要注意的事项。

上文的最后也说了,选择轮子的时候,要选择有人维护的,使用者多的轮子,这样可以避免一些问题。但是如果你的需求或者功能比较小众,这个领域轮子少,用的人也少,那么该如果选择?

我推荐如下几个策略。

  1. 向该领域的专家、前辈、同事请教,问下这个领域内大家都使用哪些轮子来处理的
  2. 同等条件下,优先使用大厂(比如Google,Alibaba)或大机构(如Apache)的轮子
  3. 同等条件下,优先使用issue活跃的轮子,这样至少出了问题,大家可以一起讨论,一起解决
  4. 同等条件下,优先使用代码逻辑清晰、优雅的代码,这样无论是对排查问题,甚至自行修改都是好的
  5. 最后的办法,就是自己造一个轮子了,但是如果能依赖别人的轮子来造,也是推荐的

选好的轮子,那么如果防范别人的轮子里有炸呢?我也推荐如下几条策略。

- 阅读剩余部分 -

本周开始做搜索功能优化,这边的搜索功能主要用的是ES。代码写好提测给测试同学的时候,测试同学说搜不出东西,我排查了下,是ES的索引的mapping同线上不一致,线上的mapping增加了三个分词插件,分别是ik,NGram,pinyin,搜索的时候对这些插件扩展字段进行的搜索。

现在就是要把测试环境的索引mapping修改成同线上一致的,我采用的是下面的方案:

  1. 新建一个原索引(index)的备份索引(index_bak),这个备份索引采用线上一致的settings和mappings,可以直接将线上的settings和mappings复制到json文件里。

    curl -XPUT 'http://127.0.0.1:9200/index_bak' -d '@create_index_bak.json'

- 阅读剩余部分 -

最近有这么一个需求,要给每个用户生成一个唯一的邀请码,用户可以将这个邀请码分享出去,当新用户使用这个邀请码注册登录的时候,就会给邀请者和被邀请者双方发放奖励。

常见的方法有如下几种:

  1. 直接使用用户uid做邀请码,简单直接,就好像其他app中填入邀请者的手机号一样
  2. 对uid做hash生成一串字符串做邀请码,这个主要是为了避免用户的uid泄露,但是要保存用户uid和邀请码的对应关系
  3. 采用对称加密算法加密uid,这样直接根据邀请码就可以解出用户uid,不需要保存uid和邀请码的对应关系了

我们这边的用户uid是纯数字的,共有13位,给这13位uid生成hash或加密的话,结果会较长,不方便用户分享和填写,产品经理限制邀请码长度为6位,同时生成的邀请码中不能要oO1ILl等容易混淆的字符。

- 阅读剩余部分 -