需求分析
1.登录效果图
2.登录需求
登录方式:手机号码+手机验证码
3.从登录model中获取手机号和验证码,首先判断手机号或验证码是否为空,其次判断验证码与输入验证码是否一致,
4.如果没有注册,第一次登录首先根据该手机号是否存在,如果不存在就自动注册
5.检测用户状态(0:锁定;1:正常)
基于Token的身份验证方法
JWT介绍
JWT(json web Token)是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准,JWT最重要的作用就是对token信息的防伪作用.
用户model
用户所需字段:
字段名 | 字段含义 |
---|---|
phone | 手机号 |
nickName | 昵称 |
name | 用户姓名 |
authStatus | 认证状态(0:未认证;1:认证中;2:认证成功;-1认证失败) |
status | 账号状态(0:锁定;1:正常) |
@ApiModelProperty(value = "昵称")
@TableField("nick_name")
private String nickName;
@ApiModelProperty(value = "手机号")
@TableField("phone")
private String phone;
@ApiModelProperty(value = "用户姓名")
@TableField("name")
private String name;
@ApiModelProperty(value = "认证状态(0:未认证 1:认证中 2:认证成功 -1:认证失败)")
@TableField("auth_status")
private Integer authStatus;
@ApiModelProperty(value = "状态(0:锁定 1:正常)")
@TableField("status")
private Integer status;
登录model
登录所需字段
字段名 | 字段含义 |
---|---|
phone | 手机号 |
code | 验证码 |
ip | ip地址 |
@ApiModelProperty(value = "手机号")
private String phone;
@ApiModelProperty(value = "密码")
private String code;
@ApiModelProperty(value = "IP")
private String ip;
登录实现
Controller层接口
//用户短信登录
@ApiOperation("用户短信登录")
@GetMapping("sendMessage/{phone}")
public Result sendMessage(@PathVariable String phone){
String code = userInfoService.sendMessage(phone);
return Result.ok(code);
}
service层接口
容联云发送短信接口
public String sendMessage(String phone) {
HashMap<String, Object> result = null;
CCPRestSmsSDK restAPI = new CCPRestSmsSDK();
restAPI.init("sandboxapp.cloopen.com", "8883");
restAPI.init("app.cloopen.com", "8883");
restAPI.setAccount("8aaf07087f77bf96017f97ec8e4a0b5b",
"19b686a45d2a499fb1084993c809a327");//account和token
restAPI.setAppId("8aaf07087f77bf96017f97ec8f660b62");
String code = randCode(5);//生成随机数验证码
System.out.println(code);
result = restAPI.sendTemplateSMS(phone,"1" ,new String[]{code,"1"});
System.out.println("SDKTestGetSubAccounts result=" + result);
if("000000".equals(result.get("statusCode"))){
//正常返回输出data包体信息(map)
HashMap<String,Object> data = (HashMap<String, Object>) result.get("data");
Set<String> keySet = data.keySet();
for(String key:keySet){
Object object = data.get(key);
System.out.println(key +" = "+object);
}
return code;
}else{
//异常返回输出错误码和错误信息
System.out.println("错误码=" + result.get("statusCode") +" 错误信息= "+result.get("statusMsg"));
return null;
}
}
生成五位验证码函数
//随机验证码
public static String randCode(Integer len){
StringBuilder builder=new StringBuilder();
Random random=new Random();
for (int i = 0; i <len; i++) {
//产生0-9的随机数 根据len参数
int nextInt = random.nextInt(10);
//把int类型转换成string类型
builder.append(String.valueOf(nextInt));
}
return builder.toString();
}
用户登录接口
//从loginVo获取手机号和验证码
String phone = loginVo.getPhone();
String code1 = loginVo.getCode();
//判断手机号或验证码是否为空
if (StringUtils.isEmpty(phone)||StringUtils.isEmpty(code1)){
throw new YyghException(ResultCodeEnum.PARAM_ERROR);
}
System.out.println(code+"sssssssssssssssss");
//TODO 判断验证码与输入验证码是否一致
if (!code.equals(loginVo.getCode())){
throw new YyghException(ResultCodeEnum.CODE_ERROR);
}
//判断是否第一次登录 根据手机号查询数据库,如果不存在相同手机号 就是第一次登录注册到数据库中
QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
wrapper.eq("phone",phone);
UserInfo userInfo = baseMapper.selectOne(wrapper);
if (userInfo==null){
userInfo = new UserInfo();
userInfo.setPhone(phone);
userInfo.setName("");
userInfo.setStatus(1);
baseMapper.insert(userInfo);
}
//校验状态是否登录
if (userInfo.getStatus()==0){
throw new YyghException(ResultCodeEnum.LOGIN_DISABLED_ERROR);
}
//不是第一次登录直接登录
Map<String,Object> map = new HashMap<>();
String name = userInfo.getName();
if (StringUtils.isEmpty(name)){
name = userInfo.getNickName();
}
if (StringUtils.isEmpty(name)){
name = userInfo.getPhone();
}
map.put("name",name);
//jwt生成token
String token = JwtHelper.createToken(userInfo.getId(), name);
map.put("token",token);
return map;
Swagger进行测试
- 输入手机号
- 查看测试结果
- 查看手机验证短信
手机收到短信并且验证码和swagger测试相同,测试成功
整合前端测试
- 输入手机号进行登录
- 输入错误验证码
- 输入正确验证码