亚洲乱色熟女一区二区三区丝袜,天堂√中文最新版在线,亚洲精品乱码久久久久久蜜桃图片,香蕉久久久久久av成人,欧美丰满熟妇bbb久久久

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

用戶注冊(cè)這樣玩,保你平安

freeflydom
2023年12月1日 12:0 本文熱度 1411

前言

基本上每個(gè)系統(tǒng)系統(tǒng)都包含用戶注冊(cè)、發(fā)送驗(yàn)證碼等基本操作。在前些年,我還記得我在逛 csdn、貼吧、網(wǎng)易新聞等網(wǎng)站的時(shí)候是可以不登陸也能瀏覽完網(wǎng)頁內(nèi)容的,但是近幾年這些網(wǎng)站已經(jīng)改成了不登陸不讓用,瀏覽網(wǎng)頁時(shí)不時(shí)提醒你要進(jìn)行登錄,對(duì)于一些不喜歡注冊(cè)的用戶造成了相當(dāng)大的困擾。

但是不知道大家有沒有想過這里面的深層邏輯,就是為什么前些年什么 csdn、貼吧、網(wǎng)易新聞等明明不進(jìn)行登錄瀏覽網(wǎng)頁體驗(yàn)還行,現(xiàn)在要改成這樣子?

這里面涉及的因素有很多,比如互聯(lián)網(wǎng)發(fā)展到頭、變現(xiàn)困難、存量環(huán)境加劇內(nèi)卷等。

當(dāng)公司盈利壓力變大,老板眼看收益日趨降低,便開始拉領(lǐng)導(dǎo)開會(huì),領(lǐng)導(dǎo)開完會(huì)開始 PUA 員工,一層一層遞進(jìn),輔以績(jī)效、okr 等工具制定目標(biāo)結(jié)果。于是公司底層員工的想法從努力賺錢、升職加薪變成保住飯碗、養(yǎng)活一家老小,對(duì)于業(yè)務(wù)上的月度、季度營(yíng)收要求自然是各種促進(jìn)用戶付費(fèi)的手段應(yīng)上齊上。

這里面提升付費(fèi)有一個(gè)非常重要的前提就是用戶,只要有了用戶就有付費(fèi)希望。

如果用戶不注冊(cè),不留下手機(jī)號(hào)、郵箱等個(gè)人信息,互聯(lián)網(wǎng)運(yùn)營(yíng)又怎么給這些用戶發(fā)送營(yíng)銷短信和郵件。所以說強(qiáng)制注冊(cè)本質(zhì)上是為了公司利益。

只要把用戶留下來,留在自己的 APP 里,收集用戶信息,后續(xù)各種運(yùn)營(yíng)活動(dòng)、支付彈窗、短信找回、活動(dòng)抽獎(jiǎng)一起上,何愁沒有用戶 😜。

用戶信息記錄的意義是為了聚集 C 端用戶、收集信息,為后續(xù)運(yùn)營(yíng)活動(dòng)(提升付費(fèi))做準(zhǔn)備。就拿淘寶舉例,個(gè)性化推薦、千人千面、雙 11 活動(dòng)等,這一系列運(yùn)營(yíng)活動(dòng)說到底都是為了提升淘寶的付費(fèi)金額,提升淘寶平臺(tái)的 GMV。什么個(gè)性化推薦、千人千面說白了就是收集你的個(gè)人信息,你的商品點(diǎn)擊、瀏覽、下單等操作都會(huì)被淘寶采集,進(jìn)而通過算法模型進(jìn)行商品推薦,選出你可能感興趣的商品展示,從而提升淘寶付費(fèi)金額。

OK,到這里題外話說多了,雖然說用戶注冊(cè)是一個(gè)很基本的邏輯,但是很多人一不小心就會(huì)掉坑里。這里我給大家介紹下 waynboot-mall 項(xiàng)目中用戶注冊(cè)是怎么玩的,為什么說可以保你平安。

waynboot-mall 項(xiàng)目是由我開源的一套 H5 商城項(xiàng)目,包含運(yùn)營(yíng)后臺(tái)、H5 商城前臺(tái)和服務(wù)端接口。實(shí)現(xiàn)了商城所需的首頁展示、商品分類、商品詳情、商品 sku、分詞搜索、購物車、結(jié)算下單、支付寶/微信支付、收單評(píng)論以及完善的后臺(tái)管理等一系列功能。 技術(shù)上基于最新得 Springboot3.0 框架開發(fā)而來,整合了 MySql、Redis、RabbitMQ、ElasticSearch 等常用中間件。商城模塊劃分合理、代碼質(zhì)量較高、易于部署,非常適合大家拿來學(xué)習(xí)使用。

github 地址:https://github.com/wayn111/waynboot-mall

用戶注冊(cè)

在 waynboot-mall 項(xiàng)目中,商城注冊(cè)頁面截圖如下。

/captcha 生成圖形驗(yàn)證碼接口

@ResponseBody

@RequestMapping("/captcha")

public R captcha() {

    // 1. 創(chuàng)建驗(yàn)證碼對(duì)象,定義驗(yàn)證碼圖形的長(zhǎng)、寬、以及字?jǐn)?shù)

    SpecCaptcha specCaptcha = new SpecCaptcha(80, 32, 4);

    // 2. 生成驗(yàn)證碼

    String verCode = specCaptcha.text().toLowerCase();

    // 3. 生成驗(yàn)證碼唯一key

    String captchaKey = IdUtil.getUid();

    // 4. 存入redis并設(shè)置過期時(shí)間為30分鐘

    redisCache.setCacheObject(captchaKey, verCode, SysConstants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);

    // 5. 將key和base64返回給前端

    return R.success().add("captchaKey", captchaKey).add("image", specCaptcha.toBase64());

}

驗(yàn)證碼接口基本是每個(gè)系統(tǒng)都有的接口,驗(yàn)證碼主要是為了防止別人直接調(diào)用接口進(jìn)行注冊(cè)操作,是一個(gè)安全措施。現(xiàn)在市面上流行的有圖形驗(yàn)證碼、滑塊驗(yàn)證碼、點(diǎn)選驗(yàn)證碼等,waynboot-mall 項(xiàng)目中使用的圖形驗(yàn)證碼,大家有興趣可以了解 tianai-captcha 這個(gè)項(xiàng)目,包含滑塊驗(yàn)證碼、點(diǎn)選驗(yàn)證碼等。現(xiàn)在我們對(duì)驗(yàn)證碼接口進(jìn)行講解,

  • 第一步,創(chuàng)建驗(yàn)證碼對(duì)象,定義驗(yàn)證碼圖形的長(zhǎng)、寬、以及字?jǐn)?shù)(這里創(chuàng)建的 SpecCaptcha 對(duì)象來自 easy-captcha 項(xiàng)目)

  • 第二步,生成驗(yàn)證碼 verCode

  • 第三步,為驗(yàn)證碼生成唯一 captchaKey

  • 第四步,將 captchaKey 作為 key, verCode 作為 value,存入 redis 并設(shè)置過期時(shí)間

  • 第五步,將 captchaKey 以及驗(yàn)證碼圖像的 base64 編碼返回給前端

前端在調(diào)用完 /captcha 接口后,會(huì)拿到 captchaKey 以及驗(yàn)證碼圖像的 base64 編碼,之后前端就可以將 base64 編碼作為 img 標(biāo)簽 src 屬性用作圖形驗(yàn)證碼展示。

用戶輸入郵箱和圖形驗(yàn)證碼后就可以點(diǎn)擊發(fā)送郵箱驗(yàn)證碼了。

調(diào)用發(fā)送郵箱驗(yàn)證碼接口時(shí)會(huì)將 captchaKey、驗(yàn)證碼、手機(jī)號(hào)等信息一起傳給服務(wù)端。

/sendEmailCode 發(fā)送郵箱驗(yàn)證碼接口

@PostMapping("/sendEmailCode")

public R sendEmailCode(@RequestBody RegistryObj registryObj) {

    String captchaKey = registryObj.getCaptchaKey();

    String captchaCode = registryObj.getCaptchaCode();

    String mobile = registryObj.getMobile();

    if (StringUtils.isBlank(captchaKey)) {

        return R.error(CUSTOM_ERROR.setMsg("圖形驗(yàn)證碼錯(cuò)誤"));

    }

    if (StringUtils.isBlank(captchaCode)) {

        return R.error(CUSTOM_ERROR.setMsg("圖形驗(yàn)證碼為空"));

    }

    if (StringUtils.isBlank(mobile)) {

        return R.error(CUSTOM_ERROR.setMsg("手機(jī)號(hào)為空"));

    }

    String redisCode = redisCache.getCacheObject(captchaKey);

    // 判斷驗(yàn)證碼code

    if (!redisCode.equals(captchaCode.trim().toLowerCase())) {

        return R.error(USER_CAPTCHA_CODE_ERROR);

    }

    // 驗(yàn)證手機(jī)號(hào)是否唯一

    long count = iMemberService.count(Wrappers.lambdaQuery(Member.class).eq(Member::getMobile, mobile));

    if (count > 0) {

        return R.error(USER_PHONE_HAS_REGISTER_ERROR);

    }

    // 生成郵箱驗(yàn)證碼code

    String emailCode = RandomUtil.randomString(6);

    // 生成郵箱驗(yàn)證碼唯一key

    String emailKey = RedisKeyEnum.EMAIL_KEY_CACHE.getKey(IdUtil.getUid());

    // 存入redis并設(shè)置過期時(shí)間為20分鐘

    redisCache.setCacheObject(emailKey, emailCode + "_" + mobile,  RedisKeyEnum.EMAIL_KEY_CACHE.getExpireSecond());

    commonThreadPoolTaskexecutor.execute(() -> {

        EmailConfig emailConfig = mailConfigService.getById(1L);

        SendMailVO sendMailVO = new SendMailVO();

        sendMailVO.setSubject("mall商城注冊(cè)通知");

        sendMailVO.setContent("郵箱驗(yàn)證碼:" + emailCode);

        sendMailVO.setTos(Collections.singletonList(registryObj.getEmail()));

        MailUtil.sendMail(emailConfig, sendMailVO, false, false);

    });

    return R.success().add("emailKey", emailKey);

}

一般商城系統(tǒng)中,發(fā)送郵箱驗(yàn)證碼、短信驗(yàn)證碼時(shí)都需要進(jìn)行驗(yàn)證碼輸入這一步驟,這是為了防止別人直接通過接口調(diào)用的形式,浪費(fèi)我們系統(tǒng)的資源,特別是發(fā)送手機(jī)驗(yàn)證碼、郵件這種資源。發(fā)送郵箱驗(yàn)證碼接口講解如下,

  • 第一步,校驗(yàn) captchaKey、captchaCode、mobile 必傳參數(shù)

  • 第二步,根據(jù) captchaKey 讀取 redis 中存放的驗(yàn)證碼 code,與用戶輸入 captchaCode 進(jìn)行比較

  • 第三步,驗(yàn)證用戶手機(jī)號(hào)是否唯一

  • 第四步,生成六位郵箱驗(yàn)證碼 emailCode

  • 第五步,生成郵箱驗(yàn)證碼唯一 emailKey

  • 第六步,將 emailKey 作為 key, emailCode_mobile 作為 value,存入 redis 并設(shè)置過期時(shí)間(注意這一步將用戶手機(jī)號(hào),也存入 Redis 是為了防止用戶在獲取完郵箱驗(yàn)證碼后修改手機(jī)號(hào),這一點(diǎn)很重要,很多開發(fā)同學(xué)都忘了這一步)

  • 第七步,使用線程池異步發(fā)送驗(yàn)證碼郵件

前端在調(diào)用完 /sendEmailCode 接口后,就可以拿到 emailKey。

這樣等用戶輸入郵箱里的驗(yàn)證碼后,點(diǎn)擊注冊(cè)按鈕,我們就可能正式開始注冊(cè)操作了。

/registry 用戶注冊(cè)

@PostMapping("/registry")

public R registry(@RequestBody RegistryObj registryObj) {

    // 驗(yàn)證兩次密碼輸入是否一致

    if (!StringUtils.equalsIgnoreCase(registryObj.getPassword(), registryObj.getConfirmPassword())) {

        return R.error(USER_TWO_PASSWORD_NOT_SAME_ERROR);

    }

    // 驗(yàn)證用戶手機(jī)號(hào)是否唯一

    long count = iMemberService.count(Wrappers.lambdaQuery(Member.class).eq(Member::getMobile, registryObj.getMobile()));

    if (count > 0) {

        return R.error(USER_PHONE_HAS_REGISTER_ERROR);

    }


    // 判斷圖形驗(yàn)證碼

    String redisCaptchaCode = redisCache.getCacheObject(registryObj.getCaptchaKey());

    if (registryObj.getCaptchaCode() == null || !redisCaptchaCode.equals(registryObj.getCaptchaCode().trim().toLowerCase())) {

        return R.error(USER_CAPTCHA_CODE_ERROR);

    }


    // 判斷郵箱驗(yàn)證碼

    String value = redisCache.getCacheObject(registryObj.getEmailKey());

    String[] split = value.split("_");

    if (split.length < 2) {

        return R.error(ReturnCodeEnum.USER_EMAIL_CODE_ERROR);

    }

    String redisEmailCode = split[0];

    String mobile = split[1];

    // 判斷發(fā)送郵箱驗(yàn)證碼的手機(jī)號(hào)是否與用戶當(dāng)前傳入手機(jī)號(hào)一致

    if (!StringUtils.equalsIgnoreCase(mobile, registryObj.getMobile())) {

        return R.error(ReturnCodeEnum.USER_REGISTER_MOBILE_ERROR);

    }

    // 判斷用戶輸入郵箱驗(yàn)證碼是否正確

    if (registryObj.getEmailCode() == null || !redisEmailCode.equals(registryObj.getEmailCode().trim().toLowerCase())) {

        return R.error(ReturnCodeEnum.USER_EMAIL_CODE_ERROR);

    }

    // 刪除驗(yàn)證碼

    redisCache.deleteObject(registryObj.getCaptchaKey());

    redisCache.deleteObject(registryObj.getEmailKey());

    Member member = new Member();

    long time = System.currentTimeMillis();

    member.setNickname("昵稱" + time / 1000);

    String avatar = SysConstants.DEFAULT_AVATAR;

    member.setAvatar(avatar);

    member.setMobile(registryObj.getMobile());

    member.setEmail(registryObj.getEmail());

    member.setPassword(SecurityUtils.encryptPassword(registryObj.getPassword()));

    member.setcreateTime(new Date());

    return R.result(iMemberService.save(member));

}

注冊(cè)接口,需要邏輯完善,所以這里的校驗(yàn)邏輯會(huì)比較多,因?yàn)橐粋€(gè)商城最重要的幾個(gè)接口就是注冊(cè)、登錄、下單、支付等。

除了能讓用戶正常注冊(cè)外,有時(shí)候還需要確保用戶一個(gè)手機(jī)號(hào)只能注冊(cè)一個(gè)賬號(hào),完成對(duì)用戶手機(jī)號(hào)在商城的唯一性保障。除了先查詢用戶手機(jī)號(hào)是否已存在外,還需要對(duì)用戶 member 表的手機(jī)號(hào)字段設(shè)置唯一索引來完成。注冊(cè)接口講解如下,

唯一索引可以防止用戶重復(fù)點(diǎn)擊注冊(cè)按鈕,保證一個(gè)手機(jī)號(hào)只能注冊(cè)一個(gè)用戶。

  • 第一步,驗(yàn)證用戶輸入兩次密碼是否一致

  • 第二步,驗(yàn)證用戶輸入的手機(jī)號(hào)是否唯一

  • 第三步,驗(yàn)證用戶輸入的圖形驗(yàn)證碼是否于 Redis 中存儲(chǔ)一致

  • 第四步,驗(yàn)證發(fā)送郵箱驗(yàn)證碼的手機(jī)號(hào)是否于 Redis 中存儲(chǔ)一致

  • 第五步,驗(yàn)證用戶輸入的郵箱驗(yàn)證碼是否于 Redis 中存儲(chǔ)一致

  • 第六步,校驗(yàn)通過,開始刪除圖形驗(yàn)證碼、郵箱驗(yàn)證碼

  • 第七步,啟動(dòng)線程池,異步進(jìn)行用戶保存操作

最后聊兩句

用戶注冊(cè)說簡(jiǎn)單是很簡(jiǎn)單,但是校驗(yàn)邏輯一定要做好!這是我的踩坑經(jīng)驗(yàn),現(xiàn)在我傳授給你,希望能幫你平安🤝。

作者:waynaqua

原文鏈接:https://www.cnblogs.com/waynaqua/p/17868631.html



該文章在 2023/12/1 14:18:52 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲(chǔ)管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved