探花交友day01

目录

1.获取验证码

1.2获取验证码

2.校验验证码

2.1Tken介绍

2.3远程调用根据手机号查询用户和添加的方法 

3.今天遇到的小问题



具体步骤:

1.1获取验证码

1.2.校验验证码

1.获取验证码

获取验证码我用的是阿里云获取验证码 

我把他抽取成了一个工具类

SmsProperties 这里设置了自动装配类 @ConfigurationProperties(prefix = "tanhua.sms") 


@Data
@ConfigurationProperties(prefix = "tanhua.sms")
public class SmsProperties {
    private String smsSignId; //签名
    private String templateId; //模板
    private String appcode;
}

探花交友day01_第1张图片

配置文件spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.tanhua.autoconfig.TanhuaAutoConfiguration

探花交友day01_第2张图片

SmsTemplate 类

public class SmsTemplate {

    private SmsProperties properties;

    public SmsTemplate (SmsProperties properties) {
        this.properties = properties;
    }

    public void sendSms(String mobile,String code) {

        //请求连接
        String host = "https://gyytz.market.alicloudapi.com/sms/smsSend";
        //拼装请求体
        Map querys = new HashMap();
        querys.put("mobile", mobile);
        querys.put("param", "**code**:"+code+",**minute**:5");
        querys.put("smsSignId", properties.getSmsSignId());
        querys.put("templateId", properties.getTemplateId());

        try {
            String result = HttpRequest.post(host)
                    .header(Header.AUTHORIZATION, "APPCODE " + properties.getAppcode())//头信息,多个头信息多次调用此方法即可
                    .form(querys)//表单内容
                    .timeout(20000)//超时,毫秒
                    .execute().body();
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

要发送验证码就直接可以调用工具类的方式即可

1.2获取验证码

controller代码 没什么可说的,就是把json格式的参数转换成字符串

 /**
     *
     * @param map 手机号是jsno格式的
     * @return 返回一个状态吗
     */
    @PostMapping("/login")
    public ResponseEntity login(@RequestBody Map map){
        String phone = (String) map.get("phone");

           userService.sendMsg(phone);

        return ResponseEntity.status(200).body("成功");
    }

Service层 

1.先 调用template发送短信
    smsTemplate.sendSms(phone, code);

2.把验证码存到redis里面方便验证 

  @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private SmsTemplate smsTemplate;

    @DubboReference
    private UserApi userApi;

    //获取验证码
    public void sendMsg(String phone) {

        //1、生成验证码(6位数字)
       String code = RandomStringUtils.randomNumeric(6);
    //  String code ="123456";
        //2、调用template发送短信
        smsTemplate.sendSms(phone, code);
        //3、存入redis
        redisTemplate.opsForValue().set("CHECK_CODE_" + phone, code, Duration.ofMinutes(5));//验证码失效时间
        //4、构建返回值

2.校验验证码

controller层 这一层没啥好说的

  /** 用户登录
     * /user/loginVerification 验证码校验
     * phone 手机号
     * verificationCode	验证码
     *
     */
  @PostMapping("/loginVerification")
    public ResponseEntity loginVerification(@RequestBody Map map){

      String phone = (String) map.get("phone");
      String code = (String) map.get("verificationCode");
   return userService.loginVerification(phone, code);//校验手机号

  }

service层 这一层就有点东西了

1.先去Redis里面根据手机号为key的形式获取到验证码值然后对比

2.如果跟用户的验证码保持一致就调用根据手机号查询用户的方法,反之就报500异常(如果通过了之后记得要删除redis里面的缓存)

3.根据手机号查询用户,如果用户对象是空就帮他重创建一个,并且获取他的id

4.把用户手机号和id传递给Tken工具类生成一个Tken

5.把生成的Tken值返回出去

 public ResponseEntity loginVerification(String phone, String code) {
        //从Redis里面获取验证码
        String vlue = redisTemplate.opsForValue().get("CHECK_CODE_" + phone);
        //1.判断验证码是否正确、
        if (code.isEmpty()||!code.equals(vlue)) {
            //2.验证码不正确或者为空抛出一个异常
            return ResponseEntity.status(500).body(ErrorResult.loginError());
        }
        redisTemplate.delete("CHECK_CODE_" + phone);// 清除redis中的验证码数据
        //3.登录成功查询用户
        User user = userApi.findByMobile(phone);
        //查询用户是否为空,为空就是没注册,然后自动注册
        boolean isNew = false;
        if (user == null) {
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("123456"));
            Long userId = userApi.save(user);
            user.setId(userId);
            isNew = true;
        } //4.通过JWT生成Token
        Map map = new HashMap();
        map.put("id", user.getId());
        map.put("mobile", phone);
        String token = JwtUtils.getToken(map);
        //5、构造返回值
        Map retmap = new HashMap();
        retmap.put("token", token);
        retmap.put("isNew", isNew);
        return ResponseEntity.ok(retmap);


    }

2.1Tken介绍

JSON Web Token简称JWT,用于对应用程序上用户进行身份验证的标记。使用 JWTS 之后不需要保存用户的 cookie 或其他session数据,同时可保证应用程序的安全。

JWT是经过加密处理与校验处理的字符串,形式为:A.B.C

  1. –A由JWT头部信息header加密得到

  2. –B由JWT用到的身份验证信息JSON数据加密得到

  3. –C由A和B加密得到,是校验部分

  4. –官方测试网站: JSON Web Tokens - jwt.io

public class JwtUtils {

    // TOKEN的有效期1小时(S)
    private static final int TOKEN_TIME_OUT = 3_600;

    // 加密KEY
    private static final String TOKEN_SECRET = "itcast";


    // 生成Token
    public static String getToken(Map params){
        long currentTime = System.currentTimeMillis();
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, TOKEN_SECRET) //加密方式
                .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
                .addClaims(params) 传递过来的要封装成Tken的值,为map格式
                .compact();
    }


    /**
     * 获取Token中的claims信息
     */
    private static Claims getClaims(String token) {
        return Jwts.parser()
                .setSigningKey(TOKEN_SECRET)
                .parseClaimsJws(token).getBody();
    }


    /**
     * 是否有效 true-有效,false-失效
     */
    public static boolean verifyToken(String token) {

        if(StringUtils.isEmpty(token)) {
            return false;
        }

        try {
            Claims claims = Jwts.parser()
                    .setSigningKey("itcast")
                    .parseClaimsJws(token)
                    .getBody();
        }catch (Exception e) {
            return false;
        }

        return true;
    }

2.3远程调用根据手机号查询用户和添加的方法 

UserApi接口 远程调用调他就完事了 (在这里我们是直接抽取成了api方法直接远程调用)

//用户Api

public interface UserApi {

    //根据用户手机号查找用户
    User  findByMobile(String mobile);

    //添加一个用户。并且返回他的用户id
    Long save(User user);
}

UserApiImpl实现Api

@DubboService //暴露远程调用的接口

public class UserApiImpl implements UserApi{

    @Autowired
   private UserMapper userMapper;
    /**
     * 根据用户手机号IU查找用户
     * @param mobile 手机号
     * @return 用户信息
     */
    @Override
    public User findByMobile(String mobile) {
        QueryWrapper qw = new QueryWrapper<>();
        qw.eq("mobile",mobile);
        return userMapper.selectOne(qw);

   
     * @param user 要存入的用户数据
     * @return 返回一个用户Id
     */
    @Override
    public Long save(User user) {
        userMapper.insert(user);
        return user.getId();
    }
}

操作数据库直接用Mybatis plus

3.今天遇到的小问题

1.获取验证码登录的时候总是会显示验证码错误,可是我明明已经设置了验证码是123456的默认值

探花交友day01_第3张图片

 探花交友day01_第4张图片

 问题解决 

探花交友day01_第5张图片

2.远程调用的时候的细节问题

探花交友day01_第6张图片

 问题排查与解决:这里的注解我不小心写成了@Autowired注入了

 应该改成DubboReference才对的

你可能感兴趣的:(java,java,spring)