阿里云短信服务实现免密登陆
2018-02-24 23:22
609 查看
使用阿里云的短信服务,实现免密登陆。
一. 阿里云短信服务申请。
1、首先,得有个阿里云账号,在控制台找到短信服务。
2、 在签名管理中根据步骤添加签名,这个之后就是你验证码短信中最开始的【】中的内容,譬如阿里云的短信,【阿里云】xxx 。申请可能审核不通过,它会提示你原因,我一开始未通过是因为在申请说明中需要填写你项目的网址,或者项目名称。这个签名后面会用到。
3、在模板管理中添加模板,上面有模板库让你参考,譬如,”您的验证码:${code},您正进行身份验证,打死不告诉别人!”,根据自己需求可以再改改,只要不是一些敏感内容即可。通过后有个模板CODE后面会用到,SMS_前缀加一串数字的那个。
二. 密钥申请&下载短信发送API的SDK
如图:
在Access Key管理中创建,可以获得公钥和私钥,之后会使用。
我使用的是JAVA的,SDK包里包括一个aliyun-java-sdk-core包,一个alicom-dysms-api包。
下载后放入项目中,我选择新建一个lib文件夹,然后再pom文件中添加依赖
然后在配置文件中添加阿里云短信的配置,我是在全局配置文件application.properties中添加,
三. 发送验证码功能
可以参考其样例程序。
接口就不贴了。
Controller层:
成功短信示例:
四. 登陆功能
使用的Spring Security管理,部分代码省略。
其实只是想记录下如何用阿里云短信服务实现发送验证码,所以后面的可以忽略啦。
一. 阿里云短信服务申请。
1、首先,得有个阿里云账号,在控制台找到短信服务。
2、 在签名管理中根据步骤添加签名,这个之后就是你验证码短信中最开始的【】中的内容,譬如阿里云的短信,【阿里云】xxx 。申请可能审核不通过,它会提示你原因,我一开始未通过是因为在申请说明中需要填写你项目的网址,或者项目名称。这个签名后面会用到。
3、在模板管理中添加模板,上面有模板库让你参考,譬如,”您的验证码:${code},您正进行身份验证,打死不告诉别人!”,根据自己需求可以再改改,只要不是一些敏感内容即可。通过后有个模板CODE后面会用到,SMS_前缀加一串数字的那个。
二. 密钥申请&下载短信发送API的SDK
如图:
在Access Key管理中创建,可以获得公钥和私钥,之后会使用。
我使用的是JAVA的,SDK包里包括一个aliyun-java-sdk-core包,一个alicom-dysms-api包。
下载后放入项目中,我选择新建一个lib文件夹,然后再pom文件中添加依赖
<!-- 阿里云短信服务 --> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>3.3.1</version> <scope>system</scope> <systemPath>${project.basedir}/lib/aliyun-java-sdk-core-3.3.1.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>
然后在配置文件中添加阿里云短信的配置,我是在全局配置文件application.properties中添加,
# 阿里云短信 aliyun.sms.accessKey=你的 aliyun.sms.accessKeySecret=你的 aliyun.sms.template.code=SMS_你的
三. 发送验证码功能
可以参考其样例程序。
接口就不贴了。
@Service public class SmsServiceImpl implements ISmsService, InitializingBean { @Value("${aliyun.sms.accessKey}") private String accessKey; @Value("${aliyun.sms.accessKeySecret}") private String scretKey; @Value("${aliyun.sms.template.code}") private String templateCode; private IAcsClient acsClient; @Autowired private RedisTemplate<String, String> redisTemplate; private static final String SMS_CODE_CONTENT_PREFIX = "SMS::CODE:CONTENT::"; private static final 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; //从redis缓存中通过key获取 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); // 短信模板 SMS_CODE request.setTemplateCode(templateCode); // 短信签名 request.setSignName("Orcas栈"); boolean success = false; try { SendSmsResponse response = acsClient.getAcsResponse(request); //判断sms验证码发送是否成功 if ("OK".equals(response.getCode())) { success = true; } else { return new ServiceResult<String>(false, "验证码发送失败!"); } } catch (ClientException e) { e.printStackTrace(); } if (success) { // 短信发送成功, 存入redis缓存中 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"); // 初始化ascClient IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKey, scretKey); String product = "Dysmsapi"; // 短信API产品名称,固定 String domain = "dysmsapi.aliyuncs.com"; // 短信API产品域名,固定 DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain); this.acsClient = new DefaultAcsClient(profile); } /** * 6位验证码生成器 * @return */ private static String generateRandomSmsCode() { StringBuilder sb = new StringBuilder(); //NUMS[10] for (int i = 0; i < 6; i++) { int index = random.nextInt(10); sb.append(NUMS[index]); } return sb.toString(); } }
Controller层:
@GetMapping("/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()); } }
成功短信示例:
四. 登陆功能
使用的Spring Security管理,部分代码省略。
public class AuthFilter extends UsernamePasswordAuthenticationFilter { @Autowired private IUserService userService; @Autowired private ISmsService smsService; @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String name = obtainUsername(request); if (!Strings.isNullOrEmpty(name)) { //用户名密码登陆 request.setAttribute("username", name); return super.attemptAuthentication(request, response); } //手机登陆 String telephone = request.getParameter("telephone"); if (Strings.isNullOrEmpty(telephone) || !LoginUserUtil.checkTelephone(telephone)) { throw new BadCredentialsException("Wrong telephone number"); } User user = userService.findUserByTelephone(telephone); String inputCode = request.getParameter("smsCode"); String sessionCode = smsService.getSmsCode(telephone); if (Objects.equals(inputCode, sessionCode)) { if (user == null) { //手机号未注册 注册该用户 user = userService.addUserByPhone(telephone); } return new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities()); } else { throw new BadCredentialsException("smsCodeError"); } } }
@Service public class UserServiceImpl implements IUserService{ @Autowired private UserRepository userRepository; @Autowired private RoleRepository roleRepository; @Override public User findUserByName(String userName) { User user = userRepository.findByName(userName); if (user == null) { return null; } List<Role> roles = roleRepository.findRolesByUserId(user.getId()); if (roles == null || roles.isEmpty()) { throw new DisabledException("权限非法"); } List<GrantedAuthority> authorities = new ArrayList<>(); roles.forEach(role -> authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()))); user.setAuthorityList(authorities); return user; } @Override public User findUserByTelephone(String telephone) { User user = userRepository.findUserByPhoneNumber(telephone); if (user == null) { return null; } List<Role> roles = roleRepository.findRolesByUserId(user.getId()); if (roles == null || roles.isEmpty()) { throw new DisabledException("权限非法"); } List<GrantedAuthority> authorities = new ArrayList<>(); roles.forEach(role -> authorities.add(new SimpleGrantedAuthority("ROLE_" + role.getName()))); user.setAuthorityList(authorities); return user; } @Override @Transactional public User addUserByPhone(String telephone) { User user = new User(); user.setPhoneNumber(telephone); user.setName(telephone.substring(0, 3) + "****" + telephone.substring(7, telephone.length())); user.setCreatTime(new Date()); user.setLastUpdateTime(new Date()); user.setLastLoginTime(new Date()); user = userRepository.save(user); Role role = new Role(); role.setName("USER"); role.setUserId(user.getId()); roleRepository.save(role); user.setAuthorityList(Lists.newArrayList(new SimpleGrantedAuthority("ROLE_USER"))); return user; } }
其实只是想记录下如何用阿里云短信服务实现发送验证码,所以后面的可以忽略啦。
相关文章推荐
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送功能
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- java实现对阿里云消息服务实现发送短信
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- php 阿里云短信服务及阿里大于实现短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- laravel5.4使用Laravel Sms和阿里云短信服务实现短信验证码功能
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- 调用阿里云短信服务平台API实现ERP系统短信发送功能
- 阿里云 短信服务实现
- Springboot实现阿里云通信短信服务有关短信验证码的发送
- Springboot实现阿里云通信短信服务有关短信验证码的发送