安卓+SpringBoot短信验证
Posted weixin_52173611
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓+SpringBoot短信验证相关的知识,希望对你有一定的参考价值。
安卓+SpringBoot短信验证
原理
客户端进入登陆页面,输入手机号,点击"获取验证码",这时候客户端会先做一个判断,看手机号是不是符合规范,不是的话就弹出提示框提示"手机号不规范,请重新输入",如果是规范的手机号,客户端就带上手机号作为参数向服务端发送请求,服务端接收到这个请求就调用发送短信的业务层(官方有工具类,输入参数即可),随机生成四位数字,然后可以以这个手机号为key,验证码为value存在redis,设置一个过期时间(一般都是五分钟),然后这个业务层会向这个手机号发送这个随机生成的字符串。
客户端收到短信输入验证码,点击登录,客户端又带上手机号和验证码向服务端发送请求,服务端收到请求首先看redis是不是存在这样的"以客户端提交的这个手机号为key,验证码为value"的键值对,不存在的话那就是验证码过期了,或者手机号,验证填错了,返回验证错误的信息给客户端;如果存在的话,那就验证成功了,那么接下来还要做一个判断,要看看这个手机号注册过没有,在用户注册表中查询有没有这个手机号对应的用户,有的话就是注册过的,那就返回客户端登陆成功的标识,客户端成功登录跳转首页;如果用户注册表中没有对应的用户,可以返回客户端没有注册的信息,也可以顺便用这个手机号注册一个信息,现在一般都是这种流程,注册之后,同样返回客户端登录成功的信息,客户端登陆成功,跳转首页。
流程图:
步骤:
客户端
这是安卓端登录页的代码:
package com.yunyou.fragment.Login;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.yunyou.R;
import com.yunyou.entity.Scenics.JsonRootBean;
import com.yunyou.fragment.PersonalFragment;
import com.yunyou.module.MainActivity;
import com.yunyou.utils.YyHttpRequestOrGetDataFromNet;
import com.yunyou.utils.YySharedPrefUtility;
import org.json.JSONObject;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Create by xie
* Date: 2021/10/11
* Time: 0:03
**/
public class LoginByIdentityCodeFragment extends Fragment implements View.OnClickListener
private String phone;
private String vertify;
private String jsonLoginningInfo;
private JsonRootBean jsonRootBean;//自己写的实体类,格式化数据
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
final View view = inflater.inflate(R.layout.activity_login_by_identitycode, container, false);
Button vertify = view.findViewById(R.id.vertify);
Button loginvertify = view.findViewById(R.id.loginvertify);
vertify.setOnClickListener(this);
loginvertify.setOnClickListener(this);
return view;
//这是碎片的实例化
public static LoginByIdentityCodeFragment newInstance()
Bundle bundle = new Bundle();
LoginByIdentityCodeFragment fragment = new LoginByIdentityCodeFragment();
fragment.setArguments(bundle);
return fragment;
//这是登录的方法
public void login()
EditText phoneEditView = getView().findViewById(R.id.phone_account);
phone = phoneEditView.getText().toString();
EditText vertifyEditView = getView().findViewById(R.id.edit_passwordvertify);
vertify = vertifyEditView.getText().toString();
//正确的手机号
if(isTruePhone(phone))
// Toast.makeText(getActivity(),"验证码已发送至"+phone+"五分钟内有效,注意查收哦!",Toast.LENGTH_LONG).show();
try
//后端验证登录的接口
String loginurl = getString(R.string.url2) + "vertify/"+phone+"/"+vertify;;
jsonLoginningInfo = YyHttpRequestOrGetDataFromNet.doGetJsonStringFromThread(loginurl, "");
Gson gson = new Gson();
jsonRootBean = gson.fromJson(jsonLoginningInfo,new TypeToken<JsonRootBean>().getType());
//token 存储
YySharedPrefUtility.setParam(getActivity(),YySharedPrefUtility.Token,
jsonRootBean.getContent().getToken());
System.out.println("token:"+jsonRootBean.getContent().getToken());
System.out.println("token:"+jsonRootBean.getMsg());
catch (Exception e) e.printStackTrace();
//密码正确:服务端返回1
if (jsonRootBean.getMsg().equals("registerSuccess"))
Toast.makeText(getActivity(), "登陆成功", Toast.LENGTH_SHORT).show();
YySharedPrefUtility.setParam(getActivity(),
YySharedPrefUtility.ACCOUNTID, phone);//用户名存起来
startActivity(new Intent(getActivity(), MainActivity.class));//登录成功跳转首页
//用户名不存在或密码错误:服务端返回-1
else
Toast.makeText(getActivity(), "手机号不存在或验证码不正确", Toast.LENGTH_SHORT).show();
//验证码为空
else if(vertify.equals(""))
Toast.makeText(getActivity(),"验证码不能为空",Toast.LENGTH_LONG).show();
//不是合格的手机号
else
Toast.makeText(getActivity(),"不是合格的手机号",Toast.LENGTH_LONG).show();
//发送验证码
public void sendSms()
EditText phoneEditView = getView().findViewById(R.id.phone_account);
phone = phoneEditView.getText().toString();
if(!isTruePhone(phone))
Toast.makeText(getActivity(),"不是合格的手机号"+phone,Toast.LENGTH_LONG).show();
else
//这里请求url
try
String loginByVertifyurl = getString(R.string.url2) + "send/"+phone;
String result = YyHttpRequestOrGetDataFromNet.doGetJsonStringFromThread(loginByVertifyurl,"cdvdv");
Toast.makeText(getActivity(),"验证码已发送至"+phone+"五分钟内有效,注意查收哦!",Toast.LENGTH_LONG).show();
catch (Exception e) e.printStackTrace();
//验证是否为合格的手机号
public Boolean isTruePhone(String phone)
// ^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d8$
// String PHONE_PATTERN="^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17([0,1,6,7,]))|(18[0-2,5-9]))\\\\d8$";
String PHONE_PATTERN = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147)|(19[0-9]))\\\\d8$";
boolean isPhone = Pattern.compile(PHONE_PATTERN).matcher(phone).matches();
if(isPhone)return true;
else return false;
/**
* 8-16个字符,不包含空格,必须包含数字,字母或字符至少两种
* @param password
* @return
*/
public boolean isPassword(String password)
String pattern = "(?!.*\\\\s)(?!^[\\\\u4e00-\\\\u9fa5]+$)(?!^[0-9]+$)(?!^[A-z]+$)(?!^[^A-z0-9]+$)^.8,16$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(password);
return m.matches();
/**
* 验证是否为邮箱
* @param email
* @return
*/
public boolean isEmail(String email)
String pattern = "^\\\\w+([-+.]\\\\w+)*@\\\\w+([-.]\\\\w+)*\\\\.\\\\w+([-.]\\\\w+)*$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(email);
return m.matches();
//点击事件
@Override
public void onClick(View v)
switch (v.getId())
//发送验证码
case R.id.vertify:
sendSms();
break;
//登录
case R.id.loginvertify:
login();
break;
服务端
配置redis
服务端为了实现验证码过期的逻辑,要用到redis,那首先就要配置redis,我之前用ssm项目配置redis一直有问题,于是就叫别人帮忙把项目转成了SpringBoot开发
1.下载redis
最好在github,在官网现在只能下载压缩包,压缩文件用也是可以用,但是每次都要手动开启redis服务,重新设置redis密码买比较繁琐,最好在github下载二进制文件安装包,地址如下:
https://github.com/tporadowski/redis/releases
下载后进入redis安装目录进入redis.windows.conf
找到这一行,改成你的密码
然后可能要在redis安装目录下cmd输入redis-server.exe redis.windows.conf执行这个配置文件才会生效
反正最后在双击redis-cli 输入"auth 123456"(自己的密码)出现OK就是设置成功
2.添加依赖
<!--redis-Jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--spring-reids-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
3.写redis配置文件
applecation.properties
spring.redis.host=localhost
#Redis服务器连接端口
spring.redis.port=6379
#Redis服务器连接密码(默认为空)
spring.redis.password=123456
#spring.redis.database=0
#连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=8
#连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
#连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
#连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
#连接超时时间(毫秒)
spring.redis.timeout=30000
RedisConfig配置类读取applecation.properties信息
package com.yunyou.yunyoutest.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class JedisConfig
@Value("$spring.redis.host")
private String host;
@Value("$spring.redis.port")
private int port;
@Value("$spring.redis.password")
private String password;
@Value("$spring.redis.timeout")
private int timeout;
@Value("$spring.redis.jedis.pool.max-active")
private int maxActive;
@Value("$spring.redis.jedis.pool.max-idle")
private int maxIdle;
@Value("$spring.redis.jedis.pool.max-wait")
private long maxWait;
@Value("$spring.redis.jedis.pool.max-idle")
private int minIdle;
@Bean
public JedisPool jedisProvider()
try
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(maxIdle);
config.setMaxWaitMillis(maxWait);
config.setMaxTotal(maxActive);
config.setMinIdle(minIdle);
JedisPool jedisPool = new JedisPool(config, host, port, timeout, password);
System.out.println("连接redis" + jedisPool.getResource().toString());
return jedisPool;
catch (Exception e)
System.out.println(e);
System.out.println(host+port+timeout+ password);
System.out.println("redis连接失败");
return null;
还有一个redis的工具类
package com.yunyou.yunyoutest.util.Redis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
import java.util.Map;
@Component
public class JedisUtils
@Autowired(required = false)
private JedisPool jedisPool;
/**
* 获取JedisPool连接池实例
*
* @return JedisPool连接池实例(通过Spring生成)
*/
public JedisPool getJedisPool()
return jedisPool;
/**
* 获取Jedis实例
*
* @return Jedis实例
*/
public Jedis getJedis()
return jedisPool.getResource();
/**
* Redis设置键值对
*
* @param key 键
* @param value 值
* @return 值
*/
public String set(String key, String value)
return action(jedis -> jedis.set(key, value));
/**
* Redis获取键对应的值
*
* @param key 键
* @return 值
*/
public String get(String key)
return action(jedis -> jedis.get(key));
/**
* Redis是否存在当前键
*
* @param key 查询的键
* @return 是否存在
*/
public Boolean exists(String key)
return action(jedis -> jedis.exists(key));
/**
* 设置Key的过期时间,单位以秒计
*
* @param key 键
* @param seconds 秒数
* @return 1为设置成功,0为设置失败(Jedis返回的就是Long,不知道为嘛要用Long)
*/
public Long expire(String key, int seconds)
return action(jedis -> jedis.expire(key, seconds));
以上是关于安卓+SpringBoot短信验证的主要内容,如果未能解决你的问题,请参考以下文章