本文共 10834 字,大约阅读时间需要 36 分钟。
登入阿里云,找到短信服务,开通短信功能记住一些重要的数据,这里不多说。
大概就是这个样子:
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); Mapmap = 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/