博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于springboot+shiro阿里云短信服务实现短信验证登入
阅读量:3951 次
发布时间:2019-05-24

本文共 10834 字,大约阅读时间需要 36 分钟。

1、前期准备

登入阿里云,找到短信服务,开通短信功能记住一些重要的数据,这里不多说。

大概就是这个样子:

在这里插入图片描述

2、一些重要的参数密钥

在这里插入图片描述

3、代码部分

1、配置参数类

/*  Created by IntelliJ IDEA.  User: Kalvin  Date: 2020/10/26  Time: 19:52*/package com.music.system.config;public class StaticPeram {
/** * 手机验证部分配置 */ // 设置超时时间-可自行调整 public final static String defaultConnectTimeout = "sun.net.client.defaultConnectTimeout"; public final static String defaultReadTimeout = "sun.net.client.defaultReadTimeout"; public final static String Timeout = "10000"; // 初始化ascClient需要的几个参数 public final static String product = "Dysmsapi";// 短信API产品名称(短信产品名固定,无需修改) public final static String domain = "dysmsapi.aliyuncs.com";// 短信API产品域名(接口地址固定,无需修改) // 替换成你的AK (产品密) public final static String accessKeyId = "LTAI4G8UycM9iECpovbs6zrY";// 你的accessKeyId,填你自己的 上文配置所得 自行配置 public final static String accessKeySecret = "6WC5fYmoVetc95Na08zVoDP5RuydzH";// 你的accessKeySecret,填你自己的 上文配置所得 自行配置 // 必填:短信签名-可在短信控制台中找到 public final static String SignName = "网欲音乐"; // 阿里云配置你自己的短信签名填入 // 必填:短信模板-可在短信控制台中找到 public final static String TemplateCode = "SMS_205122284"; // 阿里云配置你自己的短信模板填入}

2、编写短信验证码生成工具,同时把验证码存到redis中设置过期时间

jedisClient.set(mobile+“code”,code,120);

/*  Created by IntelliJ IDEA.  User: Kalvin  Date: 2020/10/26  Time: 19:52*/package com.music.utils;import com.alibaba.fastjson.JSONObject;import com.aliyuncs.CommonRequest;import com.aliyuncs.CommonResponse;import com.aliyuncs.DefaultAcsClient;import com.aliyuncs.IAcsClient;import com.aliyuncs.exceptions.ClientException;import com.aliyuncs.exceptions.ServerException;import com.aliyuncs.http.MethodType;import com.aliyuncs.profile.DefaultProfile;import com.music.system.config.StaticPeram;import javax.annotation.Resource;import java.util.HashMap;import java.util.Map;public class PhoneCode {
/** * 阿里云短信服务配置 * @param mobile * @return */ public static CommonResponse getPhonemsg(String mobile,JedisClient jedisClient) {
String code = vcode(); jedisClient.set(mobile+"code",code,120); DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", StaticPeram.accessKeyId, StaticPeram.accessKeySecret); IAcsClient client = new DefaultAcsClient(profile); CommonRequest request = new CommonRequest(); request.setSysMethod(MethodType.POST); request.setSysDomain(StaticPeram.domain); request.setSysVersion("2017-05-25"); request.setSysAction("SendSms"); request.putQueryParameter("RegionId", "cn-hangzhou"); request.putQueryParameter("PhoneNumbers", mobile); request.putQueryParameter("SignName", StaticPeram.SignName); request.putQueryParameter("TemplateCode", StaticPeram.TemplateCode); Map
map = new HashMap<>(); map.put("code",code); request.putQueryParameter("TemplateParam", JSONObject.toJSONString(map)); CommonResponse response = null; try {
response = client.getCommonResponse(request); System.out.println(response.getData()); } catch (ServerException e) {
e.printStackTrace(); } catch (ClientException e) {
e.printStackTrace(); } return response; } /** * 生成6位随机数验证码 * @return */ public static String vcode(){
String vcode = ""; for (int i = 0; i < 6; i++) {
vcode = vcode + (int)(Math.random() * 9); } return vcode; }}

3、短信验证登入realm

package com.music.system.shiro.realm;import com.music.model.User;import com.music.service.impl.UserService;import com.music.utils.JedisClient;import lombok.extern.slf4j.Slf4j;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import javax.annotation.Resource;/** * 手机验证码登录realm */@Slf4jpublic class UserPhoneRealm extends AuthorizingRealm {
@Autowired private UserService userService; @Resource JedisClient jedisClient; @Override public String getName() {
return LoginType.USER_PHONE.getType(); } @Override public boolean supports(AuthenticationToken token) {
if (token instanceof UserToken) {
return ((UserToken) token).getLoginType() == LoginType.USER_PHONE; } else {
return false; } } @Override public void setAuthorizationCacheName(String authorizationCacheName) {
super.setAuthorizationCacheName(authorizationCacheName); } @Override protected void clearCachedAuthorizationInfo(PrincipalCollection principals) {
super.clearCachedAuthorizationInfo(principals); } /** * 认证信息.(身份验证) : Authentication 是用来验证用户身份 * */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
log.info("---------------- 手机验证码登录 ----------------------"); UserToken token = (UserToken) authcToken; String phone = token.getUsername(); // 手机验证码 String validCode = String.valueOf(token.getPassword()); System.out.println("validCode------>"+validCode); // 这里从redis中获取了验证码为 123456,并对比密码是否正确 String redisCode = jedisClient.get(phone+"code"); System.out.println("redisCode------>"+redisCode); //线上用redisCode取代123456 if(!redisCode.equals(validCode)){
log.debug("验证码错误,手机号为:{}", phone); throw new IncorrectCredentialsException(); } User user = userService.findUserByPhone(phone); if(user == null){
throw new UnknownAccountException(); } // 用户为禁用状态 if(!user.getShow()){
throw new DisabledAccountException(); } SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo( user, //用户 validCode, //密码 getName() //realm name ); return authenticationInfo; } /** * 授权 */ @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
return null; }}
/*  Created by IntelliJ IDEA.  User: Kalvin  Date: 2020/10/26  Time: 12:29*/package com.music.controller;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.music.model.User;import com.music.service.IUserService;import com.music.service.impl.UserService;import com.music.system.enums.ResultStatusCode;import com.music.system.shiro.realm.LoginType;import com.music.system.shiro.realm.UserToken;import com.music.system.vo.Result;import com.music.utils.JedisClient;import com.music.utils.OptionalLog;import com.music.utils.PhoneCode;import org.apache.shiro.SecurityUtils;import org.apache.shiro.authc.IncorrectCredentialsException;import org.apache.shiro.authc.LockedAccountException;import org.apache.shiro.authc.UnknownAccountException;import org.apache.shiro.subject.Subject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import java.util.Map;import static com.music.system.shiro.realm.LoginType.USER_PASSWORD;import static com.music.system.shiro.realm.LoginType.USER_PHONE;@CrossOrigin@RestController@RequestMapping("admin")public class LoginController {
@Autowired private UserService userService; @Resource JedisClient jedisClient; /** * 用户密码登录 */ @RequestMapping("/login") public Result login(HttpServletRequest request){
String loginName = request.getParameter("name"); String password = request.getParameter("password"); request.getSession().setAttribute("loginName",loginName); System.out.println("我是登录页的"+request.getSession().getAttribute("loginName")); System.out.println(loginName+"---->"+password); UserToken token = new UserToken(LoginType.USER_PASSWORD, loginName, password); return shiroLogin(token,LoginType.USER_PASSWORD); } /** * 用户点击获取验证码请求 * */ @RequestMapping("/sentCode") public Result sentCode(@RequestBody Map map){
String phone = (String)map.get("phone"); System.out.println("phone----->"+phone); // PhoneCode.getPhonemsg(phone,jedisClient); //上线打开注释 return new Result(1); } /** * 手机验证码登录 */ @RequestMapping("/loginByPhone") public Result loginByPhone(@RequestBody Map map){
String phone = (String)map.get("phone"); String code = (String)map.get("code"); System.out.println(phone+"---->"+code); UserToken token = new UserToken(LoginType.USER_PHONE, phone, code); System.out.println("token---->"+token); return shiroLogin(token,LoginType.USER_PHONE); } @OptionalLog(modules="操作日志", methods="查询操作日志") @RequestMapping("/query") public void listLogInfo(){
System.out.println("我进入来了。。。。"); } public Result shiroLogin(UserToken token,LoginType loginType){
User user = null; String userName = null; String phone = null; try {
//登录不在该处处理,交由shiro处理 Subject subject = SecurityUtils.getSubject(); System.out.println("subject-------->"+subject); if(LoginType.USER_PASSWORD.equals(loginType)){
userName = token.getUsername(); user = userService.findUserByName(userName); }else if(LoginType.USER_PHONE.equals(loginType)){
phone = token.getUsername(); user = userService.findUserByPhone(phone); } System.out.println(phone+"================="+userName); //出现异常 subject.login(token); if (subject.isAuthenticated()&&user!=null) {
JSON json = new JSONObject(); ((JSONObject) json).put("token", subject.getSession().getId()); ((JSONObject) json).put("user",user); return new Result(ResultStatusCode.OK, json); }else{
return new Result(ResultStatusCode.SHIRO_ERROR); } }catch (IncorrectCredentialsException | UnknownAccountException e){
e.printStackTrace(); return new Result(ResultStatusCode.NOT_EXIST_USER_OR_ERROR_PWD); }catch (LockedAccountException e){
e.printStackTrace(); return new Result(ResultStatusCode.USER_FROZEN); }catch (Exception e){
e.printStackTrace(); return new Result(ResultStatusCode.SYSTEM_ERR); } }}

若对shiro不清楚可以先去了解一下在来看看效果会更好些。

这部分可以连接到上一篇文章.
同时你可以关注微信公众号:幽灵邀请函 回复短信验证获取整个项目源代码,这里声明一下只是项目中的部分代码,和大家分享。

转载地址:http://snuzi.baihongyu.com/

你可能感兴趣的文章
【Redis】Centos7下安装Redis
查看>>
【Redis】Centos7下搭建Redis集群
查看>>
【Redis】Centos7下搭建Redis集群——哨兵模式
查看>>
【Linux】本地ping不同VM虚拟机
查看>>
【SpringCloud】Hystrix
查看>>
快速阅读——《认知篇》
查看>>
【Asp.net】基本概念
查看>>
【Asp.net】Web服务器控件
查看>>
【Asp.net】内置对象
查看>>
C语言数据类型笔记 by STP
查看>>
C语言指针笔记 by STP
查看>>
CoreLocation笔记 by STP
查看>>
Application Transport Security has blocked a cleartext HTTP (http://) 解决方案
查看>>
The identity used to sign the executable is no longer valid.解决方案
查看>>
Xcode增加pch文件
查看>>
CocoaPods安装和使用笔记 by STP
查看>>
Could not find developer disk image-解决方案
查看>>
升级Xcode之后VVDocumenter-Xcode不能用的解决办法
查看>>
iOS开发常见报错及解决方案 by STP
查看>>
SVN(Cornerstone)屏蔽/忽略不需要版本控制的UserInterfaceState.xcuserstate
查看>>