Supplement to springboot login module-implementation steps of mobile phone SMS quick login

With the continuous development of technology, the traditional account and password login methods are being replaced by third-party logins such as QQ and WeChat and mobile SMS verification logins. This article records in detail the experience of the rapid development of mobile SMS.

1. Design Ideas
1. First, the user’s mobile phone number is required. When the user enters the mobile phone number to obtain the verification code, a parameter verification of the mobile phone number is required, and then the user table in the database is queried according to the mobile phone number to determine whether the user is Exist, for non-existent user mobile phone numbers, a prompt message will be thrown out in an abnormal manner.
2. When the information in the database is matched successfully, the function of sending verification is realized. First, automatically generate a six-digit verification code, and then call the Alibaba Cloud SMS service template (because I use Alibaba Cloud SMS service, the specific Alibaba Cloud SMS service application, and the content of the SMS template sent are relatively simple), For SMS sending, it may return false if it fails to send SMS (for example, the SMS charged by Alibaba Cloud runs out of money), and it returns true if it succeeds.
3. After the SMS is sent successfully, save the user's mobile phone number and the verification code generated and sent by the system in redis, and set the effective time for 5 minutes when storing. In this way, the function of sending SMS verification codes is over.
4. When the user obtains the verification code, and submits the mobile phone number and verification code, use the user's mobile phone number to retrieve the sent verification code from redis. If it is empty, it proves that it has timed out and throws an exception to the user. When it is not empty, check it with the verification code uploaded by the user. When they are not the same, a verification code error prompt will be thrown. When they are the same, the user information will be stored in a cookie and returned to the user as true.
5. When the user receives true from the backend, they can enter the system internal page. At this time, the front-end is passed to the back-end with the cookie, and the back-end receives the cookie, and obtains user information from redis according to the token (sessionid stored in it) and displays it on the page.
Two, code implementation,
use to introduce dependencies

<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-core</artifactId>
		<version>4.0.6</version>
	</dependency>
	<dependency>
		<groupId>com.aliyun</groupId>
		<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
		<version>1.1.0</version>
	</dependency>

The first is the preparation of Alibaba Cloud SMS tools, where sending SMS and generating verification code are put together.

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.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import org.springframework.stereotype.Component;
@Component
public class AliPhoneCodeUtils {
    
    
    //产品名称:云通信短信API产品,开发者无需替换
    static final String product = "Dysmsapi";
    //产品域名,开发者无需替换
    static final String domain = "dysmsapi.aliyuncs.com";
    static final String accessKeyId = "用户自己申请的";
    static final String accessKeySecret = "用户自己申请的";
    private int newcode;
    public  int getNewcode() {
    
    
            return newcode;
        }
    public void setNewcode(){
    
    
            newcode = (int)(Math.random()*999999)+100;
            //每次调用生成一位6位数的随机数
        }
    //发送注册验证码
    public  Boolean sendSms(String telephone, String code) throws ClientException {
    
    
     //可自助调整超时时间
        System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
        System.setProperty("sun.net.client.defaultReadTimeout", "10000");
        //初始化acsClient,暂不支持region化
        IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
        IAcsClient acsClient = new DefaultAcsClient(profile);
        //组装请求对象-具体描述见控制台-文档部分内容
        SendSmsRequest request = new SendSmsRequest();
        //必填:待发送手机号
        request.setPhoneNumbers(telephone);
        //必填:短信签名-可在短信控制台中找到
        request.setSignName("XXX");
            //必填:短信模板-可在短信控制台中找到
        request.setTemplateCode("XXXX");
        request.setTemplateParam("{\"code\":\"" + code + "\"}");
        request.setOutId("yourOutId");
        SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
        if(sendSmsResponse.getCode()!= null && sendSmsResponse.getCode().equals("OK")){
    
    
            return true;
        }else {
    
    
            return false;
        }
    }

Controller layer

  @PostMapping(value = "/login_code_phone")
    public ResponseResult<Boolean> login_phone_submit(HttpServletResponse response,
                                                      @Valid LoginPhoneCodeVO loginPhoneCodeVO){
    
    
        userService.checkLogin_phone(response,loginPhoneCodeVO);
        return ResponseResult.success(true);
    }
    @PostMapping(value = "/get_phoneCode")
    public ResponseResult<Boolean> get_PhoneCode(@Valid phone_ajax phone) throws ClientException {
    
    
        userService.sendPhoneCode(phone);
        return ResponseResult.success(true);
    }

There are two parameters to verify
LoginPhoneCodeVo and phone_ajax, IsPhone annotations are customized

import com.example.validator.IsPhone;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public class LoginPhoneCodeVO {
    
    
    @IsPhone
    @NotEmpty(message = "手机号不能为空!")
    private String phone;
    @NotEmpty(message = "验证码不能为空!")
    private String code;
    @Override
    public String toString() {
    
    
        return "LoginPhoneCodeVO{" +
                "phone='" + phone + '\'' +
                ", code='" + code + '\'' +
                '}';
    }
import com.example.validator.IsPhone;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
@Data
public class phone_ajax {
    
    
    @IsPhone
    @NotEmpty(message = "手机号不能为空!")
    private String phone;
}

Service layer, which involves redis, global exception content, and result package content

public boolean sendPhoneCode(phone_ajax phone) throws ClientException {
    
    
        if(userMapper.selectUserById(phone.getPhone())==null){
    
    
            throw new GlobalException(ResponseCode.PHONE_NOT_FOUND);
        }
        aliPhoneCodeUtils.setNewcode();
        String phone1 = phone.getPhone();
        String code = String.valueOf(aliPhoneCodeUtils.getNewcode());
        String key = PHONE_CODE_PROFX+phone1;
        redisService.set_Time(key,code,time_phone_code);
        if(!aliPhoneCodeUtils.sendSms(phone1,code)) {
    
    
            throw new GlobalException(ResponseCode.SEND_SMS_ERROR);
        }
        return true;
    }
    /**1.
     * */
    public boolean checkLogin_phone(HttpServletResponse response,LoginPhoneCodeVO loginPhoneCodeVO){
    
    
        if(loginPhoneCodeVO==null){
    
    
            throw new GlobalException(ResponseCode.USER_INFORMATION_ERROR);
        }
        String phone = loginPhoneCodeVO.getPhone();
        String code = loginPhoneCodeVO.getCode();
        User user = userMapper.selectUserById(phone);
        if(user==null){
    
    
            throw new GlobalException(ResponseCode.PHONE_NOT_FOUND);
        }else {
    
    
            String key = PHONE_CODE_PROFX+phone;
            String code1 = (String) redisService.get(key);
            if(code.equals(code1)==false){
    
    
                throw new GlobalException(ResponseCode.PHONE_CODE_ERROR);
            }
        }
        addCookie(response,user);
        return true;
    }

Guess you like

Origin blog.csdn.net/Wangdiankun/article/details/106354682