【瑞吉外卖】day08:短信发送、手机验证码登录(三)

简介: 【瑞吉外卖】day08:短信发送、手机验证码登录

5.2 数据模型


通过手机验证码登录时,涉及的表为user表,即用户表。结构如下:image.png

5.3 前端页面分析


在开发代码之前,需要梳理一下登录时前端页面和服务端的交互过程:

1). 在登录页面(front/page/login.html)输入手机号,点击【获取验证码】按钮,页面发送ajax请求,在服务端调用短信服务API给指定手机号发送验证码短信。

image.png

image.png

如果服务端返回的登录成功,页面将会把当前登录用户的手机号存储在sessionStorage中,并跳转到移动的首页页面。



开发手机验证码登录功能,其实就是在服务端编写代码去处理前端页面发送的这2次请求即可,分别是获取短信验证码 和 登录请求,具体的请求信息如下:


1). 获取短信验证码

请求 说明
请求方式 POST
请求路径 /user/sendMsg
请求参数 {"phone":"13100001111"}

2). 登录

请求 说明
请求方式 POST
请求路径 /user/login
请求参数 {"phone":"13100001111", "code":"1111"}

5.4 代码开发


5.4.1 准备工作


在开发业务功能前,先将需要用到的类和接口基本结构创建好:

1). 实体类 User(直接从课程资料中导入即可)

所属包: com.itheima.reggie.entity

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#770088">import</span><spanstyle="color:#000000">lombok</span>.<spanstyle="color:#000000">Data</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">java</span>.<spanstyle="color:#000000">io</span>.<spanstyle="color:#000000">Serializable</span>;
<spanstyle="color:#aa5500">/**</span><span style="color:#aa5500">* 用户信息</span><span style="color:#aa5500">*/</span><spanstyle="color:#555555">@Data</span><spanstyle="color:#770088">public</span><spanstyle="color:#770088">class</span><spanstyle="color:#0000ff">User</span><spanstyle="color:#770088">implements</span><spanstyle="color:#000000">Serializable</span> {
<spanstyle="color:#770088">private</span><spanstyle="color:#770088">static</span><spanstyle="color:#770088">final</span><spanstyle="color:#008855">long</span><spanstyle="color:#000000">serialVersionUID</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#116644">1L</span>;
<spanstyle="color:#770088">private</span><spanstyle="color:#008855">Long</span><spanstyle="color:#000000">id</span>;
<spanstyle="color:#aa5500">//姓名</span><spanstyle="color:#770088">private</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">name</span>;
<spanstyle="color:#aa5500">//手机号</span><spanstyle="color:#770088">private</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">phone</span>;
<spanstyle="color:#aa5500">//性别 0 女 1 男</span><spanstyle="color:#770088">private</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">sex</span>;
<spanstyle="color:#aa5500">//身份证号</span><spanstyle="color:#770088">private</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">idNumber</span>;
<spanstyle="color:#aa5500">//头像</span><spanstyle="color:#770088">private</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">avatar</span>;
<spanstyle="color:#aa5500">//状态 0:禁用,1:正常</span><spanstyle="color:#770088">private</span><spanstyle="color:#008855">Integer</span><spanstyle="color:#000000">status</span>;
}</span></span>

2). Mapper接口 UserMapper

所属包: com.itheima.reggie.mapper

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">baomidou</span>.<spanstyle="color:#000000">mybatisplus</span>.<spanstyle="color:#000000">core</span>.<spanstyle="color:#000000">mapper</span>.<spanstyle="color:#000000">BaseMapper</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">itheima</span>.<spanstyle="color:#000000">reggie</span>.<spanstyle="color:#000000">entity</span>.<spanstyle="color:#000000">User</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">org</span>.<spanstyle="color:#000000">apache</span>.<spanstyle="color:#000000">ibatis</span>.<spanstyle="color:#000000">annotations</span>.<spanstyle="color:#000000">Mapper</span>;
<spanstyle="color:#555555">@Mapper</span><spanstyle="color:#770088">public</span><spanstyle="color:#770088">interface</span><spanstyle="color:#0000ff">UserMapper</span><spanstyle="color:#770088">extends</span><spanstyle="color:#000000">BaseMapper</span><spanstyle="color:#981a1a"><</span><spanstyle="color:#000000">User</span><spanstyle="color:#981a1a">></span>{
}</span></span>

3). 业务层接口 UserService

所属包: com.itheima.reggie.service

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">baomidou</span>.<spanstyle="color:#000000">mybatisplus</span>.<spanstyle="color:#000000">extension</span>.<spanstyle="color:#000000">service</span>.<spanstyle="color:#000000">IService</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">itheima</span>.<spanstyle="color:#000000">reggie</span>.<spanstyle="color:#000000">entity</span>.<spanstyle="color:#000000">User</span>;
<spanstyle="color:#770088">public</span><spanstyle="color:#770088">interface</span><spanstyle="color:#0000ff">UserService</span><spanstyle="color:#770088">extends</span><spanstyle="color:#000000">IService</span><spanstyle="color:#981a1a"><</span><spanstyle="color:#000000">User</span><spanstyle="color:#981a1a">></span> {
}</span></span>

4). 业务层实现类 UserServiceImpl

所属包: com.itheima.reggie.service.impl

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">baomidou</span>.<spanstyle="color:#000000">mybatisplus</span>.<spanstyle="color:#000000">extension</span>.<spanstyle="color:#000000">service</span>.<spanstyle="color:#000000">impl</span>.<spanstyle="color:#000000">ServiceImpl</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">itheima</span>.<spanstyle="color:#000000">reggie</span>.<spanstyle="color:#000000">entity</span>.<spanstyle="color:#000000">User</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">itheima</span>.<spanstyle="color:#000000">reggie</span>.<spanstyle="color:#000000">mapper</span>.<spanstyle="color:#000000">UserMapper</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">itheima</span>.<spanstyle="color:#000000">reggie</span>.<spanstyle="color:#000000">service</span>.<spanstyle="color:#000000">UserService</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">org</span>.<spanstyle="color:#000000">springframework</span>.<spanstyle="color:#000000">stereotype</span>.<spanstyle="color:#000000">Service</span>;
<spanstyle="color:#555555">@Service</span><spanstyle="color:#770088">public</span><spanstyle="color:#770088">class</span><spanstyle="color:#0000ff">UserServiceImpl</span><spanstyle="color:#770088">extends</span><spanstyle="color:#000000">ServiceImpl</span><spanstyle="color:#981a1a"><</span><spanstyle="color:#000000">UserMapper</span>,<spanstyle="color:#000000">User</span><spanstyle="color:#981a1a">></span><spanstyle="color:#770088">implements</span><spanstyle="color:#000000">UserService</span>{
}</span></span>

5). 控制层 UserController

所属包: com.itheima.reggie.controller

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#770088">import</span><spanstyle="color:#000000">com</span>.<spanstyle="color:#000000">itheima</span>.<spanstyle="color:#000000">reggie</span>.<spanstyle="color:#000000">service</span>.<spanstyle="color:#000000">UserService</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">lombok</span>.<spanstyle="color:#000000">extern</span>.<spanstyle="color:#000000">slf4j</span>.<spanstyle="color:#000000">Slf4j</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">org</span>.<spanstyle="color:#000000">springframework</span>.<spanstyle="color:#000000">beans</span>.<spanstyle="color:#000000">factory</span>.<spanstyle="color:#000000">annotation</span>.<spanstyle="color:#000000">Autowired</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">org</span>.<spanstyle="color:#000000">springframework</span>.<spanstyle="color:#000000">web</span>.<spanstyle="color:#000000">bind</span>.<spanstyle="color:#000000">annotation</span>.<spanstyle="color:#000000">RequestMapping</span>;
<spanstyle="color:#770088">import</span><spanstyle="color:#000000">org</span>.<spanstyle="color:#000000">springframework</span>.<spanstyle="color:#000000">web</span>.<spanstyle="color:#000000">bind</span>.<spanstyle="color:#000000">annotation</span>.<spanstyle="color:#000000">RestController</span>;
<spanstyle="color:#555555">@RestController</span><spanstyle="color:#555555">@RequestMapping</span>(<spanstyle="color:#aa1111">"/user"</span>)
<spanstyle="color:#555555">@Slf4j</span><spanstyle="color:#770088">public</span><spanstyle="color:#770088">class</span><spanstyle="color:#0000ff">UserController</span> {
<spanstyle="color:#555555">@Autowired</span><spanstyle="color:#770088">private</span><spanstyle="color:#000000">UserService</span><spanstyle="color:#000000">userService</span>;
}</span></span>

6). 工具类SMSUtils、ValidateCodeUtils(直接从课程资料中导入即可)

所属包: com.itheima.reggie.utils

image.png

SMSUtils : 是我们上面改造的阿里云短信发送的工具类 ;

ValidateCodeUtils : 是验证码生成的工具类 ;

5.4.2 功能实现


5.4.2.1 修改LoginCheckFilter


前面我们已经完成了LoginCheckFilter过滤器的开发,此过滤器用于检查用户的登录状态。我们在进行手机验证码登录时,发送的两个请求(获取验证码和登录)需要在此过滤器处理时直接放行。

image.png

对于移动的端的页面,也是用户登录之后,才可以访问的,那么这个时候就需要在 LoginCheckFilter 中进行判定,如果移动端用户已登录,我们获取到用户登录信息,存入ThreadLocal中(在后续的业务处理中,如果需要获取当前登录用户ID,直接从ThreadLocal中获取),然后放行。


增加如下逻辑:

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#aa5500">//4-2、判断登录状态,如果已登录,则直接放行</span><spanstyle="color:#770088">if</span>(<spanstyle="color:#000000">request</span>.<spanstyle="color:#000000">getSession</span>().<spanstyle="color:#000000">getAttribute</span>(<spanstyle="color:#aa1111">"user"</span>) <spanstyle="color:#981a1a">!=</span><spanstyle="color:#221199">null</span>){
<spanstyle="color:#000000">log</span>.<spanstyle="color:#000000">info</span>(<spanstyle="color:#aa1111">"用户已登录,用户id为:{}"</span>,<spanstyle="color:#000000">request</span>.<spanstyle="color:#000000">getSession</span>().<spanstyle="color:#000000">getAttribute</span>(<spanstyle="color:#aa1111">"user"</span>));
<spanstyle="color:#008855">Long</span><spanstyle="color:#000000">userId</span><spanstyle="color:#981a1a">=</span> (<spanstyle="color:#008855">Long</span>) <spanstyle="color:#000000">request</span>.<spanstyle="color:#000000">getSession</span>().<spanstyle="color:#000000">getAttribute</span>(<spanstyle="color:#aa1111">"user"</span>);
<spanstyle="color:#000000">BaseContext</span>.<spanstyle="color:#000000">setCurrentId</span>(<spanstyle="color:#000000">userId</span>);
<spanstyle="color:#000000">filterChain</span>.<spanstyle="color:#000000">doFilter</span>(<spanstyle="color:#000000">request</span>,<spanstyle="color:#000000">response</span>);
<spanstyle="color:#770088">return</span>;
}</span></span>

5.4.2.2 发送短信验证码


在UserController中创建方法,处理登录页面的请求,为指定手机号发送短信验证码,同时需要将手机号对应的验证码保存到Session,方便后续登录时进行比对。

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#aa5500">/**</span><span style="color:#aa5500">* 发送手机短信验证码</span><span style="color:#aa5500">* @param user</span><span style="color:#aa5500">* @return</span><span style="color:#aa5500">*/</span><spanstyle="color:#555555">@PostMapping</span>(<spanstyle="color:#aa1111">"/sendMsg"</span>)
<spanstyle="color:#770088">public</span><spanstyle="color:#000000">R</span><spanstyle="color:#981a1a"><</span><spanstyle="color:#008855">String</span><spanstyle="color:#981a1a">></span><spanstyle="color:#0000ff">sendMsg</span>(<spanstyle="color:#555555">@RequestBody</span><spanstyle="color:#000000">User</span><spanstyle="color:#000000">user</span>, <spanstyle="color:#000000">HttpSession</span><spanstyle="color:#000000">session</span>){
<spanstyle="color:#aa5500">//获取手机号</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">phone</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#000000">user</span>.<spanstyle="color:#000000">getPhone</span>();
<spanstyle="color:#770088">if</span>(<spanstyle="color:#000000">StringUtils</span>.<spanstyle="color:#000000">isNotEmpty</span>(<spanstyle="color:#000000">phone</span>)){
<spanstyle="color:#aa5500">//生成随机的4位验证码</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">code</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#000000">ValidateCodeUtils</span>.<spanstyle="color:#000000">generateValidateCode</span>(<spanstyle="color:#116644">4</span>).<spanstyle="color:#000000">toString</span>();
<spanstyle="color:#000000">log</span>.<spanstyle="color:#000000">info</span>(<spanstyle="color:#aa1111">"code={}"</span>,<spanstyle="color:#000000">code</span>);
<spanstyle="color:#aa5500">//调用阿里云提供的短信服务API完成发送短信</span><spanstyle="color:#aa5500">//SMSUtils.sendMessage("瑞吉外卖","",phone,code);</span><spanstyle="color:#aa5500">//需要将生成的验证码保存到Session</span><spanstyle="color:#000000">session</span>.<spanstyle="color:#000000">setAttribute</span>(<spanstyle="color:#000000">phone</span>,<spanstyle="color:#000000">code</span>);
<spanstyle="color:#770088">return</span><spanstyle="color:#000000">R</span>.<spanstyle="color:#000000">success</span>(<spanstyle="color:#aa1111">"手机验证码短信发送成功"</span>);
    }
<spanstyle="color:#770088">return</span><spanstyle="color:#000000">R</span>.<spanstyle="color:#000000">error</span>(<spanstyle="color:#aa1111">"短信发送失败"</span>);
}</span></span>

备注:

这里发送短信我们只需要调用封装的工具类中的方法即可,我们这个功能流程跑通,在测试中我们不用真正的发送短信,只需要将验证码信息,通过日志输出,登录时,我们直接从控制台就可以看到生成的验证码(实际上也就是发送到我们手机上的验证码)

5.4.2.3 验证码登录


在UserController中增加登录的方法 login,该方法的具体逻辑为:

1). 获取前端传递的手机号和验证码

2). 从Session中获取到手机号对应的正确的验证码

3). 进行验证码的比对 , 如果比对失败, 直接返回错误信息

4). 如果比对成功, 需要根据手机号查询当前用户, 如果用户不存在, 则自动注册一个新用户

5). 将登录用户的ID存储Session中

具体代码实现:

<spanstyle="background-color:#f8f8f8"><spanstyle="color:#333333"><spanstyle="color:#aa5500">/**</span><span style="color:#aa5500">* 移动端用户登录</span><span style="color:#aa5500">* @param map</span><span style="color:#aa5500">* @param session</span><span style="color:#aa5500">* @return</span><span style="color:#aa5500">*/</span><spanstyle="color:#555555">@PostMapping</span>(<spanstyle="color:#aa1111">"/login"</span>)
<spanstyle="color:#770088">public</span><spanstyle="color:#000000">R</span><spanstyle="color:#981a1a"><</span><spanstyle="color:#000000">User</span><spanstyle="color:#981a1a">></span><spanstyle="color:#0000ff">login</span>(<spanstyle="color:#555555">@RequestBody</span><spanstyle="color:#000000">Map</span><spanstyle="color:#000000">map</span>, <spanstyle="color:#000000">HttpSession</span><spanstyle="color:#000000">session</span>){
<spanstyle="color:#000000">log</span>.<spanstyle="color:#000000">info</span>(<spanstyle="color:#000000">map</span>.<spanstyle="color:#000000">toString</span>());
<spanstyle="color:#aa5500">//获取手机号</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">phone</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#000000">map</span>.<spanstyle="color:#000000">get</span>(<spanstyle="color:#aa1111">"phone"</span>).<spanstyle="color:#000000">toString</span>();
<spanstyle="color:#aa5500">//获取验证码</span><spanstyle="color:#008855">String</span><spanstyle="color:#000000">code</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#000000">map</span>.<spanstyle="color:#000000">get</span>(<spanstyle="color:#aa1111">"code"</span>).<spanstyle="color:#000000">toString</span>();
<spanstyle="color:#aa5500">//从Session中获取保存的验证码</span><spanstyle="color:#008855">Object</span><spanstyle="color:#000000">codeInSession</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#000000">session</span>.<spanstyle="color:#000000">getAttribute</span>(<spanstyle="color:#000000">phone</span>);
<spanstyle="color:#aa5500">//进行验证码的比对(页面提交的验证码和Session中保存的验证码比对)</span><spanstyle="color:#770088">if</span>(<spanstyle="color:#000000">codeInSession</span><spanstyle="color:#981a1a">!=</span><spanstyle="color:#221199">null</span><spanstyle="color:#981a1a">&&</span><spanstyle="color:#000000">codeInSession</span>.<spanstyle="color:#000000">equals</span>(<spanstyle="color:#000000">code</span>)){
<spanstyle="color:#aa5500">//如果能够比对成功,说明登录成功</span><spanstyle="color:#000000">LambdaQueryWrapper</span><spanstyle="color:#981a1a"><</span><spanstyle="color:#000000">User</span><spanstyle="color:#981a1a">></span><spanstyle="color:#000000">queryWrapper</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#770088">new</span><spanstyle="color:#000000">LambdaQueryWrapper</span><spanstyle="color:#981a1a"><></span>();
<spanstyle="color:#000000">queryWrapper</span>.<spanstyle="color:#000000">eq</span>(<spanstyle="color:#000000">User</span>::<spanstyle="color:#000000">getPhone</span>,<spanstyle="color:#000000">phone</span>);
<spanstyle="color:#000000">User</span><spanstyle="color:#000000">user</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#000000">userService</span>.<spanstyle="color:#000000">getOne</span>(<spanstyle="color:#000000">queryWrapper</span>);
<spanstyle="color:#770088">if</span>(<spanstyle="color:#000000">user</span><spanstyle="color:#981a1a">==</span><spanstyle="color:#221199">null</span>){
<spanstyle="color:#aa5500">//判断当前手机号对应的用户是否为新用户,如果是新用户就自动完成注册</span><spanstyle="color:#000000">user</span><spanstyle="color:#981a1a">=</span><spanstyle="color:#770088">new</span><spanstyle="color:#000000">User</span>();
<spanstyle="color:#000000">user</span>.<spanstyle="color:#000000">setPhone</span>(<spanstyle="color:#000000">phone</span>);
<spanstyle="color:#000000">user</span>.<spanstyle="color:#000000">setStatus</span>(<spanstyle="color:#116644">1</span>);
<spanstyle="color:#000000">userService</span>.<spanstyle="color:#000000">save</span>(<spanstyle="color:#000000">user</span>);
        }
<spanstyle="color:#000000">session</span>.<spanstyle="color:#000000">setAttribute</span>(<spanstyle="color:#aa1111">"user"</span>,<spanstyle="color:#000000">user</span>.<spanstyle="color:#000000">getId</span>());
<spanstyle="color:#770088">return</span><spanstyle="color:#000000">R</span>.<spanstyle="color:#000000">success</span>(<spanstyle="color:#000000">user</span>);
    }
<spanstyle="color:#770088">return</span><spanstyle="color:#000000">R</span>.<spanstyle="color:#000000">error</span>(<spanstyle="color:#aa1111">"登录失败"</span>);
}</span></span>

5.5 功能测试


代码完成后,重启服务,测试短信验证码的发送及登录功能。

1). 测试错误验证码的情况

image.png

image.png

检查user表,用户的数据也插入进来了:

image.png

相关文章
|
5月前
|
数据采集 监控 安全
阿里云短信服务+图形认证,有效降低验证码盗刷概率
阿里云短信服务+图形认证服务,有效降低验证码盗刷概率。
446 3
阿里云短信服务+图形认证,有效降低验证码盗刷概率
|
14天前
|
缓存 前端开发 IDE
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
20 0
【06】flutter完成注册页面-密码登录-手机短信验证-找回密码相关页面-并且实现静态跳转打包demo做演示-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草央千澈
|
2月前
|
安全 算法 机器人
双重防护!红娘相亲app搭建开发,婚恋交友系统登录方式,密码+验证码的优势
在婚恋交友系统中,密码和验证码是两种重要的安全措施。密码用于验证用户身份,应设置为复杂组合以防止未经授权的访问;验证码则通过图形或字符识别,防止自动化攻击如暴力破解和注册机器人。两者同时开启可显著提高安全性,防止暴力破解和自动化注册,提升用户信任感。建议要求强密码、定期更新验证码样式,并在可疑登录时增加验证码复杂性。这样既能保障用户信息安全,又兼顾了用户体验。 ![交友11111.jpg](https://ucc.alicdn.com/pic/developer-ecology/hy2p6wcvgk4oe_c9eb8d6eb8144866b0cd1d96ffb0c907.jpg)
|
3月前
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
454 4
|
4月前
Discuz! X3.5插件云诺-阿里云短信手机登录 会员登录后也无法查看附件图片的问题解决方法
Discuz! X3.5插件云诺-阿里云短信手机登录 会员登录后也无法查看附件图片的问题解决方法
51 2
|
4月前
|
安全 API PHP
港澳台验证码海外短信群发教程,利用阿里云国际如何实现境外短信操作
港澳台验证码海外短信群发教程,利用阿里云国际如何实现境外短信操作
|
4月前
|
SQL 存储 数据可视化
手机短信SQL分析技巧与方法
在手机短信应用中,SQL分析扮演着至关重要的角色
|
4月前
|
C#
C# 图形验证码实现登录校验代码
C# 图形验证码实现登录校验代码
143 2
|
4月前
|
Java
Java 登录输入的验证码
Java 登录输入的验证码
51 1
|
6月前
|
资源调度 JavaScript API
nest.js + sms 实现短信验证码登录
本文介绍了在Nest.js框架中集成短信验证码登录的实现方案,详细阐述了使用阿里云短信服务的配置流程、资质申请、短信模板设置,并提供了API调用示例和工程代码的运行步骤。
nest.js + sms 实现短信验证码登录

热门文章

最新文章