欢迎投稿

今日深度:

SpringBoot知识体系(五)基于springboot与阿里云实现免注册登录,

SpringBoot知识体系(五)基于springboot与阿里云实现免注册登录,


在自己学习慕课网瓦力老师的课程时,总结了基于springboot与阿里云实现免注册登录的实现。下面是整体的实现过程

简介

阿里云短信服务提供短信发送API接口SendSms和SendBatchSms,分别用于单个模板的短信单独或批量发送、多个短信模板的短信批量发送。短信服务(Short Message Service)是阿里云为用户提供的一种通信服务的能力。支持向国内和国际快速发送验证码、短信通知和推广短信

基于springboot与阿里云实现免注册登录,类似常用网站的免注册登录,通过使用阿里云短信服务发送验证码,并在redis中缓存验证码信息,过期清除,以实现通过手机号注册,接到验证码在一分钟内填写验证码,并跳转登录的功能。

这里只有后端的代码实现部分,前端页面等全部信息可以到github地址上面获取:
https://github.com/wqyuu/springboot-es


实战

项目基本环境以及配置:
https://blog.csdn.net/qq_37338761/article/details/102501961


pom.xml中添加依赖

<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-core</artifactId>
    <version>3.2.3</version>
    <!--<scope>system</scope>-->
    <!--<systemPath>${project.basedir}/lib/aliyun-java-sdk-core-3.2.3.jar</systemPath>-->
</dependency>
<dependency>
    <groupId>com.aliyun</groupId>
    <artifactId>aliyun-java-sdk-dysmsapi</artifactId>
    <version>1.0.0</version>
    <!--<scope>system</scope>-->
    <!--<systemPath>${project.basedir}/lib/aliyun-java-sdk-dysmsapi-1.0.0.jar</systemPath>-->
</dependency>

项目中添加阿里云的lib

由于maven中没有aliyun的依赖,所以将lib放到根目录下面

配置文件增加redis配置、阿里云短信配置

redis直接配置本地的地址,我这里使用的是免密登录,开发环境可以这么做。
redis用来缓存短信的验证码,保留10分钟,过期删除

# redis config
spring.redis.database=0
spring.redis.host=127.0.0.1
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.timeout=3000
#session
spring.session.store-type=redis

# 阿里云短信配置 注意替换自己申请的配置
aliyun.sms.accessKey=LTAI4FeWmDfk8SErg2x6*****
aliyun.sms.accessKeySecret=MbpEfvvJ1qQgzKJHUUlLlX******
aliyun.sms.template.code=SMS_175533***

Controller

import com.wqy.springbootes.base.ApiResponse;
import com.wqy.springbootes.base.LoginUserUtil;
import com.wqy.springbootes.service.IUserService;
import com.wqy.springbootes.service.ServiceResult;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {

    @Autowired
    private IUserService userService;


    @GetMapping("/user/login")
    public String loginPage(){
        return "user/login";
    }

    @GetMapping("/user/center")
    public String centerPage(){
        return "user/center";
    }

	@GetMapping(value = "sms/code")
	@ResponseBody
	public ApiResponse smsCode(@RequestParam("telephone")String telephone){
	
	    if(!LoginUserUtil.checkTelephone(telephone)){
	        return ApiResponse.ofMessage(HttpStatus.BAD_REQUEST.value(),"请输入正确手机号");
	    }
	    ServiceResult<String> result = smsService.sendSms(telephone);
	    if(result.isSuccess()){
	        return ApiResponse.ofSuccess("");
	    }else{
	        return ApiResponse.ofMessage(HttpStatus.BAD_REQUEST.value(),result.getMessage());
	    }
	
	}
}

ISmsService接口

/**
 * 验证码服务
 */
public interface ISmsService {

    /**
     * 发送验证码到指定手机 并缓存验证码 10分钟 及 请求间隔时间1分钟
     * @param telephone
     * @return
     */
    ServiceResult<String> sendSms(String telephone);

    /**
     * 获取缓存中的验证码
     * @param telephone
     * @return
     */
    String getSmsCode(String telephone);

    /**
     * 移除指定手机号的验证码缓存
     * @param telephone
     */
    void remove(String telephone);

}


SmsServiceImpl 实现类

import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

@Service
public class SmsServiceImpl implements ISmsService ,InitializingBean {

    @Value("${aliyun.sms.accessKey}")
    private String accessKey;
    @Value("${aliyun.sms.accessKeySecret}")
    private String secertKey;
    @Value("${aliyun.sms.template.code}")
    private String templateCode;

    private IAcsClient acsClient;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    private final static String SMS_CODE_CONTENT_PREFIX="SMS::CODE::CONTENT";

    private final static String NUMS[]={"0","1","2","3","4","5","6","7","8","9"};

    private static final Random random = new Random();

    @Override
    public ServiceResult<String> sendSms(String telephone) {
        String gapKey = "SMS::CODE::INTERVAL::"+telephone;
        String result = redisTemplate.opsForValue().get(gapKey);
        if(result!= null){ // 判断是否已缓存验证码
            return new ServiceResult<String>(false,"请求次数太频繁");
        }
        String code =generateRandomSmsCode(); // 生成验证码
        String templateParam = String.format("{\"code\":\"%s\"}",code); 

        //组装请求对象
        SendSmsRequest request = new SendSmsRequest();

        // 使用post提交
        request.setMethod(MethodType.POST);
        request.setPhoneNumbers(telephone);
        request.setTemplateParam(templateParam);
        request.setTemplateCode(templateCode);
        request.setSignName("wqy-es");

        boolean success = false;

        try {
            SendSmsResponse response = acsClient.getAcsResponse(request);
            if("OK".equals(response.getCode())){
                success = true;
            }else{
                //TODO  log
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        if(success){
            redisTemplate.opsForValue().set(gapKey,code,60,TimeUnit.SECONDS);
            redisTemplate.opsForValue().set(SMS_CODE_CONTENT_PREFIX+telephone,code,10,TimeUnit.MINUTES);
            return ServiceResult.of(code);
        }else{
            return new ServiceResult<String>(false,"系统忙,稍后重试");
        }
    }

    @Override
    public String getSmsCode(String telephone) {
        return this.redisTemplate.opsForValue().get(SMS_CODE_CONTENT_PREFIX+telephone);
    }

    @Override
    public void remove(String telephone) {
        this.redisTemplate.delete(SMS_CODE_CONTENT_PREFIX+telephone);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        // 设置超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout","10000");
        System.setProperty("sun.net.client.defaultReadTimeout","10000");

        IClientProfile profile = DefaultProfile.getProfile("cn-beijing",accessKey,secertKey);

        String product = "Dysmsapi";
        String domain = "dysmsapi.aliyuncs.com";

        DefaultProfile.addEndpoint("cn-beijing","cn-beijing",product,domain);
        // 初始化短信客户端
        this.acsClient = new DefaultAcsClient(profile);



    }

    private static String generateRandomSmsCode(){
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i <6 ; i++) {
            int index = random.nextInt(10);
            sb.append(NUMS[index]);
        }
        return sb.toString();
    }
}

结语

springboot可以很方便的整合各种常用框架,提升开发效率

免注册登录功能极大提升用户体验,虽然说需要后台帮助注册用户,这里要处理好登录之后,用户可以修改用户名的部分。

阿里云短信服务需要自己到阿里云官网申请,阿里云官网也包括JAVA API,使用示例,短信模板,短信签名。

参考

  • 阿里云短信服务 https://www.aliyun.com/citiao/1792456.html

  • BAT大牛亲授基于ElasticSearch的搜房网实战 https://coding.imooc.com/class/167.html

文章最后发布于: 2019-10-22 18:01:18

www.htsjk.Com true http://www.htsjk.com/shujukunews/37804.html NewsArticle SpringBoot知识体系(五)基于springboot与阿里云实现免注册登录, 在自己学习慕课网瓦力老师的课程时,总结了基于springboot与阿里云实现免注册登录的实现。下面是整体的实现过程 简介...
相关文章
    暂无相关文章
评论暂时关闭