日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

引言

Hello 大家好,這里是Anyin。

今天我們來聊一聊微信登錄注冊時遇到的一些事兒。

在我們的業務系統中,一個用戶在系統中肯定會有一個唯一標識,并且這個唯一標識一般是從系統外部獲取的,而不是系統自動生成的,例如:手機號或者身份證。

我們在微信的場景下(微信公眾號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。處理方式如下:

  • 根據當前的手機號查詢到所有的微信openid,做邏輯刪除處理
  • 根據當前的openid查詢到所有的手機號,做邏輯刪除處理
  • 根據當前手機號和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: 生產級 Spring Cloud 腳手架

分享到:
標簽:登錄
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定