<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
今天我們來聊一聊微信登入註冊遇到的一些事兒。
在我們的業務系統中,一個使用者在系統中肯定會有一個唯一標識,並且這個唯一標識一般是從系統外部獲取的,而不是系統自動生成的,例如:手機號或者身份證。
我們在微信的場景下(微信公眾號H5或者小程式),對於使用者的唯一標識一般都是手機號或者openid。在正常情況下,我們遇到的都是一個使用者只有一個微訊號,一個微訊號繫結了一個手機號,所以我們就認為三者的關係如下:
但是,理想很豐滿,現實很骨感,我們遇到的情況肯定不會如此的簡單。
當一個系統執行的足夠久,使用者量足夠多,那麼你總會遇到各種奇奇怪怪的問題。
在上一節,我們知道正常情況遇到的場景會比較簡單,使用者、微訊號、手機號三者是1:1:1的關係,也就說三者可以等價,我用其中一個資訊,總是可以查詢出另外兩個的資訊,例如:我可以用手機號,查詢出使用者ID和微信openid。
所以,根據以上思路,我們很容易設計出使用者表:cus_info ,基本表結構如下:
使用者ID | 微信openid | 使用者手機號 | 邏輯刪除 | 其他欄位 |
---|---|---|---|---|
id | openid | mobile | del_flg | ... |
但是當遇到以下2個場景的時候,這個表結構設計就無法滿足需求了。
一個使用者2個微訊號有些使用者是擁有兩個微訊號,並且繫結同一個手機號(這個邏輯可以通過微信換綁手機號實現)。
在這個場景下,一旦使用者換了個微訊號登入進入系統的時候,根據微信openid進行登入,因為表資料找不到該openid,則走註冊流程;在註冊的時候,又根據手機號查詢使用者資訊,發現使用者已經存在,返回登入流程,最終造成邏輯死迴圈。
一個使用者2個手機號另外還有一些使用者擁有2個手機號,並且繫結同一個手機號(這個邏輯在使用者授權手機號的時候新增另外一個手機號實現)。
在這個場景下,第一次使用者使用手機號A註冊並登入,我們在後端繫結了手機號A和對應的微信openid;第二次使用者使用手機號B註冊並登入,這時候資料庫會有2條記錄,不同手機號相同的openid。這樣子會導致在某些場景下(例如支付回撥),根據openid獲取使用者資訊的時候,找到2個使用者,從而導致業務異常。
以上2個問題,在不同的業務場景下,不同的人會有不同的解法。有以手機號作為使用者的唯一標識,有以微信openid作為使用者唯一標識。在這裡,我們提供以手機號作為使用者唯一標識的解法。
在這裡,我們認為一個手機號就是一個使用者,一個使用者會有多個微訊號。關係如下:
一個使用者2個微訊號針對該問題,我們在登入註冊的時候,會通過邏輯控制,保證一個手機號只能找到一個微信openid。處理方式如下:
一個使用者2個手機號針對該問題,我們在業務上做處理。因為我們認為了一個手機號就是一個使用者,如果一個使用者擁有兩個手機號,那麼在我們系統上我們認為是兩個使用者,他們的資料是相互獨立的。
另外在這個場景下,我們還需要提供一個手機號換綁的功能。這樣當用戶有2個手機號,也能給實現切換的需求。
以上,相關解決思路我們有了。那麼接下來就是設計和編碼。
根據以上,我們會設計如下2張表結構:
cus_info 使用者資訊表
使用者ID | 使用者手機號 | 邏輯刪除 | 其他欄位 |
---|---|---|---|
id | mobile | del_flg | ... |
cus_wx_info 使用者和微信關聯表
ID | 使用者手機號 | 微信appId | 微信openid | 開放平臺unionid | 邏輯刪除 | 其他欄位 |
---|---|---|---|---|---|---|
id | mobile | app_id | openid | unionid | del_flg | ... |
這裡多新增了一個app_id的欄位和unionid的欄位,是用於當我們的業務涉及到多個入口,例如微信公眾號H5入口和微信小程式。
不同的使用者在微信公眾號H5和微信小程式產生的openid可能一樣也可能不一樣,所以我們需要通過app_id來區分
同時為了關聯在微信公眾號H5和微信小程式的使用者,我們會把微信公眾號和微信小程式繫結到同一個開放平臺,這個時候會產生一個unionid,通過該標識即可以找到微信公眾號的使用者,也可以找到微信小程式的使用者。
接著我們實現一個註冊方法。
@Service public class CsInfoServiceImpl implements CsInfoService { @Autowired private CsInfoRepository csInfoRepository; @Autowired private CsWxInfoRepository csWxInfoRepository; @Autowired private CsInfoConvert csInfoConvert; @Override @Transactional(rollbackFor = Throwable.class, timeout = 60) public CsWxInfoDTO register(CsInfoRegisterDTO param) { // 根據手機號查詢使用者資訊 CsInfo info = csInfoRepository.infoByMobile(param.getMobile()); Long id = info == null ? 0 : info.getId(); // 如果使用者不存在,則建立 if(id == 0){ id = csInfoRepository.create(param.getMobile(), param.getRegisterSource().getCode()); } // 邏輯刪除當前手機號繫結的openid // 邏輯刪除當前openid繫結的手機號 csWxInfoRepository.handleOpenidMobileUnique(param.getMobile(), param.getOpenid(), param.getAppId()); // 保證當前手機號和openid在系統中1:1的關係 CsWxInfo wxInfo = csWxInfoRepository.infoByMobileOpenid(param.getMobile(), param.getOpenid(), param.getAppId()); if(wxInfo == null){ wxInfo = new CsWxInfo(); wxInfo.setAppId(param.getAppId()); wxInfo.setMobile(param.getMobile()); wxInfo.setOpenid(param.getOpenid()); wxInfo.setUnionid(param.getUnionid()); wxInfo.setAvatarUrl(param.getAvatarUrl()); wxInfo.setNickName(param.getNickName()); csWxInfoRepository.save(wxInfo); }else{ CsWxInfo model = new CsWxInfo(); model.setId(wxInfo.getId()); model.setDelFlg(Integer.valueOf(DelFlgEnum.NORMAL.getCode())); csWxInfoRepository.updateById(model); } CsWxInfoDTO result = csInfoConvert.getCsWxInfoDTO(wxInfo); result.setInfoId(id); return result; } }
其中handleOpenidMobileUnique方法對應的SQL處理如下:
<update id="loginDelByOpenIdExcludeMobile"> update cs_wx_info set del_flg = 0 ,update_time = now() <where> del_flg = 1 <if test="appId != null"> and app_id = #{appId} </if> <if test="openid != null and openid != ''"> and openid = #{openid} </if> <if test="mobile != null and mobile != ''"> and mobile != #{mobile} </if> </where> </update> <update id="loginDelByMobileExcludeOpenid"> update cs_wx_info set del_flg = 0 ,update_time = now() <where> del_flg = 1 <if test="appId != null"> and app_id = #{appId} </if> <if test="mobile != null and mobile != ''"> and mobile = #{mobile} </if> <if test="openid != null and openid != ''"> and openid != #{openid} </if> </where> </update>
至此,關於微信登入註冊遇到的一些小問題,我們找到了一個相對比較好解決方案,你還不快實踐到你自己專案上去?
相關原始碼地址:Anyin Cloud
到此這篇關於Java如何優雅的實現微信登入註冊的文章就介紹到這了,更多相關Java微信登入註冊內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45