主要分为3大部分

1.配置阿里云短信业务

2.uniapp手机登录模块设计以及信息提交

3.后端接收手机登录信息,反馈登录结果

项目地址:https://gitee.com/quxianyyy/sms-project

一步可以直接参考博主Axn_很优秀的文章,申请获取到key和secret

https://blog.csdn.net/qq_36802111/article/details/82561276?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159109985119724848343926%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159109985119724848343926&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~baidu_landing_v2~default-4-82561276.pc_v2_rank_blog_v1&utm_term=%E9%98%BF%E9%87%8C%E4%BA%91%E7%9F%AD%E4%BF%A1%E4%B8%9A%E5%8A%A1

第二步在uniapp设计一个手机登录的页面(ui框架是color-ui)

<form @submit="login"><view class="cu-form-group"><view class="title">手机号码</view><input placeholder="请输入手机号码" name="phoneNumbers" @input="change" maxlength="11" type="number"></input><view class="cu-capsule radius"><view class='cu-tag bg-blue '>+86</view><view class="cu-tag line-blue">中国大陆</view></view></view><view class="cu-form-group"><view class="title">验证码</view><input placeholder="请输入验证码" name="code" type="number" maxlength="4"></input><button class='cu-btn bg-green shadow' @tap="countDown" :disabled="this.countNum<60 && this.countNum>0?true:false"><!-- <span>{{this.$store.state.countNum<60 && this.$store.state.countNum>0?'倒计时'+this.$store.state.countNum:'验证码'}}</span> --><span>{{this.countNum<60 && this.countNum>0?this.countNum+'s':'验证码'}}</span></button></view><view><button form-type="submit">登录</button></view></form>

将接收的信息上传到后端验证

this.$http.post('/authentication/mobile', {}, {params: {mobile: params.phoneNumbers,code: params.code}})

详细参考项目地址里面的源码

第三部分为2种情况.

1.发送手机验证码的api

controller代码@GetMapping("/send/{phoneNumbers}")public String code(@PathVariable("phoneNumbers") String phoneNumbers){//调用发送方法//如果验证码存在 存在就是非过期String code=(String)redisTemplate.opsForValue().get(phoneNumbers);if (!StringUtils.isEmpty(code)){return phoneNumbers+":"+code+"已经存在,还没过期";}//如果不存在code=String.valueOf(new Random().nextLong()).substring(1,5);HashMap<String, Object> param=new HashMap<>();param.put("code",code);//如果发送成功,存手机验证码boolean isSend=sendSms.send(phoneNumbers,"SMS_189712947",param);if (isSend){redisTemplate.opsForValue().set(phoneNumbers,code,500, TimeUnit.MINUTES);return phoneNumbers+":"+code+"发送成功!";}else {return "发送失败";}}service
public boolean send(String phoneNum, String templateCode, Map<String, Object> code) {DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", "你的阿里云短信key", "密码");IAcsClient client = new DefaultAcsClient(profile);CommonRequest request = new CommonRequest();request.setMethod(MethodType.POST);request.setDomain("dysmsapi.aliyuncs.com");//不要改request.setVersion("2017-05-25");//不要改request.setAction("SendSms");//自定义的参数(手机号,验证码,签名,模版)request.putQueryParameter("PhoneNumbers", phoneNum);//手机号码request.putQueryParameter("SignName","你的签名名字");request.putQueryParameter("TemplateCode",templateCode);//模版代码//构建短信验证码
//        HashMap hashMap=new HashMap();
//        hashMap.put("code",2233);//code里面的就是你发送给用户手机的验证码request.putQueryParameter("TemplateParam", JSONObject.toJSONString(code));try {CommonResponse response = client.getCommonResponse(request);System.out.println(response.getData());return  response.getHttpResponse().isSuccess();} catch (ServerException e) {e.printStackTrace();} catch (ClientException e) {e.printStackTrace();}return false;}

2.处理上传的手机相关信息

如果是普通的boot项目,没有权限之类的控制.单独起一个接口进行参数接收,从redis根据手机号拿出验证码进行对比验证即可

如果是基于springsecuity搭建起的boot项目,因为默认只接收用户名,不能满足需求,可以通过自定义过滤器实现(完整代码参考项目地址里面)

//1.1写一个拦截器
public class SmsCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {protected SmsCodeAuthenticationFilter(String defaultFilterProcessesUrl) {//验证成功后super(defaultFilterProcessesUrl);}protected SmsCodeAuthenticationFilter(RequestMatcher requiresAuthenticationRequestMatcher) {super(requiresAuthenticationRequestMatcher);}//判断手机和验证码是否正常@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {System.out.println(request.getParameter("mobile"));System.out.println(request.getParameter("code"));System.out.println("1.--------请求手机登录------判断手机和验证码是否正常");//如果方法的类型不是POST,拒绝处理if (!request.getMethod().equals("POST")) {System.out.println("方法不是POST,手机登录结束");throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}RedisTemplate redisTemplate=(RedisTemplate) SpringContextUtil.getBean("redisTemplate");ObjectMapper objectMapper=SpringContextUtil.getBean(ObjectMapper.class);String mobile = request.getParameter("mobile");Object code=redisTemplate.opsForValue().get(mobile);httpServletResponse.setCharacterEncoding("utf-8");System.out.println("2.当前请求登录的手机号为"+mobile);/*** 情况:* 1.存在 当前处于用手机验证码登录的状态* 2.不存在 验证码过期或者还没发送验证码*///验证码不存在if (StringUtils.isEmpty(code)){System.out.println("验证码过期或未发送");CommonResult commonResult=new CommonResult(406,"验证码未发送或验证码已过期");httpServletResponse.getWriter().write(objectMapper.writeValueAsString(commonResult));return null;}//验证码存在String pcode=request.getParameter("code");System.out.println("3.判断验证码是否正确[前端传入的验证码"+pcode+"],[redis数据库存储的验证码"+code+"]");if (!code.equals(pcode)) {System.out.println("验证码错误");CommonResult commonResult=new CommonResult(407,"验证码错误");httpServletResponse.getWriter().write(objectMapper.writeValueAsString(commonResult));return null;}System.out.println("4.验证码和手机都正常,颁发token和返回用户信息");// 封装令牌SmsCodeAuthenticationToken authRequest = new SmsCodeAuthenticationToken(mobile,pcode);setDetails(request, authRequest);// 开始认证//调用SmsCodeAuthenticationProvider的authenticatereturn this.getAuthenticationManager().authenticate(authRequest);}protected void setDetails(HttpServletRequest request, SmsCodeAuthenticationToken authRequest) {authRequest.setDetails(authenticationDetailsSource.buildDetails(request));}}
//1.2配置自定义的信息存储类
package com.example.authenticationserver.authentication;import com.example.authenticationserver.pojo.MysqlUser;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;import java.util.Collection;/*** @author qm* @date 2020/5/15 13:10*/
public class SmsCodeAuthenticationToken extends AbstractAuthenticationToken {private static final long serialVersionUID = 1L;/** 身份 */private final Object principal;/** 验证码 */private String code;/** 权限 */private String role;/** 别名 */private String nickName;/** 用户信息 */private MysqlUser mysqlUser;public String getRole() {return role;}public void setRole(String role) {this.role = role;}public String getNickName() {return nickName;}public void setNickName(String nickName) {this.nickName = nickName;}public SmsCodeAuthenticationToken(Collection<? extends GrantedAuthority> authorities,MysqlUser mysqlUser,Object principal,String nickName) {super(authorities);this.principal = principal;this.mysqlUser=mysqlUser;this.nickName = nickName;}public void clear(){this.mysqlUser=null;}public SmsCodeAuthenticationToken(Object mobile, String code) {super(null);this.code=code;this.principal = mobile;setAuthenticated(false);}public SmsCodeAuthenticationToken(Object principal, String code,Collection<? extends GrantedAuthority> authorities) {super(authorities);this.code=code;this.principal = principal;// must use super, as we overridesuper.setAuthenticated(true);}public SmsCodeAuthenticationToken(Object principal,Collection<? extends GrantedAuthority> authorities,MysqlUser mysqlUser) {super(authorities);this.principal = principal;// must use super, as we overridesuper.setAuthenticated(true);this.mysqlUser=mysqlUser;}public String getCode() {return code;}public MysqlUser getMysqlUser() {return mysqlUser;}@Overridepublic Object getPrincipal() {return this.principal;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {if (isAuthenticated) {throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);}@Overridepublic void eraseCredentials() {super.eraseCredentials();}@Overridepublic Object getCredentials() {return null;}}
//1.3书写过滤器配置信息
@Component
public class SmsCodeAuthenticationSecurityConfigextends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {@Qualifier("myAuthenticationSuccessHandler")@Autowiredprivate AuthenticationSuccessHandler authenticationSuccessHandler;@Overridepublic void configure(HttpSecurity http) throws Exception {SmsCodeAuthenticationFilter smsCodeAuthenticationFilter =new SmsCodeAuthenticationFilter("/authentication/mobile");smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(authenticationSuccessHandler);SmsCodeAuthenticationProvider provider = new SmsCodeAuthenticationProvider();// 将SmsCodeAuthenticationFilter放到过滤器链的UsernamePasswordAuthenticationFilter的后面http.authenticationProvider(provider).addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);}
}
//1.4配置验证器,配置如何验证
//如何验证
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {@Autowiredprivate UserDetailsService userDetailsService;/*** 验证码和手机都没问题,开始用户操作** @param authentication* @return* @throws AuthenticationException*/@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {MysqlUserDao mysqlUserDao= SpringContextUtil.getBean(MysqlUserDao.class);System.out.println("5.--------用户验证---判断该用户是否存在于数据库,不存在则创建");String mobile=(String) authentication.getPrincipal();MysqlUser user = mysqlUserDao.findOne(mobile);if (user==null){System.out.println("6.用户未注册,用户注册开始........");MysqlUser mysqlUser = new MysqlUser();mysqlUser.setGender(0);mysqlUser.setNickName(mobile);mysqlUser.setRole("user");mysqlUser.setAccount(mobile);mysqlUser.setMobile(mobile);mysqlUser.setAvatarUrl("http://qzapp.qlogo.cn/qzapp/1104455702/80B727209F00D44C35166EB2D6B21086/30");mysqlUser.setPassword(new BCryptPasswordEncoder().encode("123"));int i = mysqlUserDao.add(mysqlUser);System.out.println("注册结果"+i);user = mysqlUserDao.findOne(mobile);}else {System.out.println("6.用户存在");}
//        //验证正常,封装用户信息返回
//        Collection<GrantedAuthority> authorities=new ArrayList<>();
//        authorities.add(new SimpleGrantedAuthority("ROLE_ADMIN"));SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;//设置权限Collection<GrantedAuthority> authorities=new ArrayList<>();authorities.add(new SimpleGrantedAuthority(user.getRole()));//其他信息SmsCodeAuthenticationToken authenticationResult =new SmsCodeAuthenticationToken(user.getAccount(),authorities,user);authenticationResult.setDetails(authenticationToken.getDetails());return authenticationResult;}//模拟手机号进行验证private void simulationVerification(String number, String pcode){//当收到验证码8888和手机号13005630595才算成功final String phone="13005630595";final String code="8888";if (!phone.equals(number)){throw new InternalAuthenticationServiceException("手机号不存在");}if (!code.equals(pcode)) {//判断验证码是否想等throw new InternalAuthenticationServiceException("验证码错误");}}//@Overridepublic boolean supports(Class<?> authentication) {return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);}
}
//1.5到安全框架的配置里面进行配置更新
@Autowired
private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;
@Overrideprotected void configure(HttpSecurity http) throws Exception {//引入短信拦截器配置http.apply(smsCodeAuthenticationSecurityConfig);
//1.6编写登录成功,如何处理(生成token和获取用户信息进行返回)
@Slf4j
@Component
public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {@Autowiredprivate ClientDetailsService clientDetailsService;//@Qualifier("defaultAuthorizationServerTokenServices")@Autowiredprivate AuthorizationServerTokenServices authorizationServerTokenServices;@Autowiredprivate ObjectMapper objectMapper;@Autowiredprivate MysqlUserDao mysqlUserDao;@Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication)throws IOException, ServletException, IOException {SmsCodeAuthenticationToken smsCodeAuthenticationToken=(SmsCodeAuthenticationToken)authentication;MysqlUser user = ((SmsCodeAuthenticationToken) authentication).getMysqlUser();smsCodeAuthenticationToken.clear();System.out.println("7.登录完成,准备返回token和用户信息");
//        Collection<GrantedAuthority> authorities=new ArrayList<>();
//        //设置权限
//        authorities.add(new SimpleGrantedAuthority("admin"));
//        SmsCodeAuthenticationToken smsCodeAuthenticationToken1=
//                new SmsCodeAuthenticationToken(authorities,"13005630595","ROLE_ADMIN","曲线");
//        System.out.println(smsCodeAuthenticationToken.getCode());
//        System.out.println(smsCodeAuthenticationToken.getPrincipal());
//        System.out.println(smsCodeAuthenticationToken);
//        System.out.println(authentication);
//        System.out.println("7.准备生成token");OAuth2AccessToken token = createToken(authentication);System.out.println("7.1:user信息"+user);System.out.println("7.2:token信息"+token);//封装用户信息和token信息返回Map map=new HashMap<>();map.put("code",200);map.put("authResult",token);//map.put("userInfo",mysqlUserDao.findOne((String) authentication.getPrincipal()));map.put("userInfo",user);response.setContentType("application/json;charset=UTF-8");response.getWriter().write(objectMapper.writeValueAsString(map));}public OAuth2AccessToken createToken(Authentication authentication){ClientDetails clientDetails=clientDetailsService.loadClientByClientId("myapp_id");TokenRequest tokenRequest = new TokenRequest(new HashMap<>(), "myapp_id",clientDetailsService.loadClientByClientId("myapp_id").getScope(), "custom");OAuth2Request oAuth2Request = tokenRequest.createOAuth2Request(clientDetails);OAuth2Authentication oAuth2Authentication = new OAuth2Authentication(oAuth2Request, authentication);OAuth2AccessToken accessToken = authorizationServerTokenServices.createAccessToken(oAuth2Authentication);return accessToken;}
}

uniapp引入阿里云短信业务相关推荐

  1. 17. 尚融宝引入阿里云短信服务

    一.使用RAM子用户 1.进入子用户管理页面 2.添加用户 3.获取子用户key AccessKeyId, AccessKeySecret 4.设置用户权限 授权:AliyunDysmsFullAcc ...

  2. 阿里云短信业务SMS

    文章目录 1. 了解阿里云用户权限操作 2. 开通阿里云短信服务 3. 添加短信模板 4. 添加签名 5. 编写测试代码 6. 编写可复用的微服务接口,实现验证码的发送 1. 了解阿里云用户权限操作 ...

  3. SpringBoot阿里云短信业务实战

    狂神说Java:https://www.bilibili.com/video/BV1c64y1M7qN 阿里云短信服务帮助文档:https://help.aliyun.com/product/4428 ...

  4. 如何开通阿里云短信业务

    目录 1.登录阿里云 2.配置短信业务 3.给用户授权 4.创建短信签名 5.申请模板 1.登录阿里云 登录成功之后,搜索短信服务 点击管理控制台,选择:已阅读协议,然后立即开通 2.配置短信业务 开 ...

  5. JAVA 实现阿里云短信发送功能

    目录 1.引入依赖 2.添加.yml配置 3.短信接口开发 4.接口调用 1.引入依赖 引入阿里云短信依赖jar包 <!--阿里云服务sdk --> <dependency>& ...

  6. SpringBoot-短信验证码-快速入门Demo(含redis)(手把手教你开通阿里云短信服务到写出个最终代码来)

    B站小狂神-此博客的内容就是看了这个视频的总结(博主自己写的哦~并非转载) 视频链接-[狂神说]通俗易懂的阿里云短信业务实战教程(露脸) 您是否还在为别人的项目有短信功能自己的却没有? 您是否还在为自 ...

  7. PHP 之阿里云短信发送

    一.阿里云短信发送函数封装 function aliyun_sms($mobile,$id,$data){// 引入阿里云短信类require_once $_SERVER['DOCUMENT_ROOT ...

  8. thinkphp5详细使用阿里云短信最新版(原大鱼)教程!

    如何使用tp5来使用阿里短信平台最新版2.0sdk,也就是所谓的前阿里大鱼. 首先我们下载官方完整包的SDK:[url]https://help.aliyun.com/document_detail/ ...

  9. vue+springboot+阿里云短信服务(集成redis实现验证码登录业务)

    阿里云短信服务-介绍 阿里云短信服务(Short Message Service)是广大企业客户快速触达手机用户所优选使用的通信能力.调用API或用群发助手,即可发送验证码.通知类和营销类短信:国内验 ...

最新文章

  1. Mysql-study
  2. 我与前端 | 因兴趣起源
  3. 如何制作并更改项目icon文件
  4. 本地共享映射文件夹进行删除操作_从集群建立到航测建模CC(Smart3D)实用操作教程...
  5. 分布式计算第四章 RMI
  6. 欢迎使用CSDN-markdown编辑器啦啦啦啦啦
  7. Python html 代码转成图片、PDF
  8. 三角形周长最短问题_2019年中考数学压轴题分析——最短路径问题8:造桥选址...
  9. C语言把浮点数转换为二进制数的方法和示例
  10. 【医学图像分割】基于matlab磁共振成像 (MRI) 数值模拟平台【含Matlab源码 826期】
  11. 离心泵CAE_3_FLUENT数值模拟
  12. [2021时空AI白皮书]时空人工智能:关键技术
  13. 关于cmd输入字符长度限制问题
  14. 免费版医疗器械计算机软件,医疗器械软件描述.docx
  15. 用js将HTML文本导出生成word文档
  16. linux下C语言mkdir,Linux C实现mkdir功能
  17. 2007年互联网发展趋势预测:RSS将成为主流
  18. 将网页内容截屏的好工具
  19. Abbkine IFKine驴抗小鼠IgG二抗,绿色荧光标记方案
  20. Obsidian学习|捕获信息

热门文章

  1. openlayer 画圆Circle实际半径解决方案
  2. RabbitMQ:Consumers的介绍和使用
  3. 娱乐 | 14个简单、有趣、好玩的Linux命令
  4. 编程实现对任意字符串的加密处理
  5. Excel文档的生成和压缩
  6. 无参考图像质量评价之可察觉模糊程度方法(JNB)
  7. GB50202-2018《建筑地基工程施工质量验收标准》免费下载
  8. YOLOv7改进之二十二:涨点神器——引入递归门控卷积(gnConv)
  9. 云栖专辑 | 阿里开发者们的20个感悟,一通百通
  10. java如何把汉字转拼音