我们系统集成了短信通知服务,这里我们进行OAuth2的扩展,使系统支持短信验证码登录。
1、在gitegg-oauth中新增SmsCaptchaTokenGranter 自定义短信验证码令牌授权处理类
/** * 短信验证码模式 */public class SmsCaptchaTokenGranter extends AbstractTokenGranter { private static final String GRANT_TYPE = "sms_captcha"; private final AuthenticationManager authenticationManager; private UrDetailsService urDetailsService; private IUrFeign urFeign; private ISmsFeign smsFeign; private RedisTemplate redisTemplate; private CaptchaService captchaService; private String captchaType; public SmsCaptchaTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, RedisTemplate redisTemplate, IUrFeign urFeign, ISmsFeign smsFeign, CaptchaService captchaService, UrDetailsService urDetailsService, String captchaType) { this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); this.redisTemplate = redisTemplate; this.captchaService = captchaService; this.captchaType = captchaType; this.smsFeign = smsFeign; this.urFeign = urFeign; this.urDetailsService = urDetailsService; } protected SmsCaptchaTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { super(tokenServices, clientDetailsService, requestFactory, grantType); this.authenticationManager = authenticationManager; } @Override protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters()); // 获取验证码类型 String captchaType = parameters.get(CaptchaConstant.CAPTCHA_TYPE); // 判断传入的验证码类型和系统配置得是否一致 if (!StringUtils.isEmpty(captchaType) && !captchaType.equals(this.captchaType)) { throw new UrDeniedAuthorizationException(ResultCodeEnum.INVALID_CAPTCHA_TYPE.getMsg()); } if (CaptchaConstant.IMAGE_CAPTCHA.equalsIgnoreCa(captchaType)) { // 图片验证码验证 String captchaKey = parameters.get(CaptchaConstant.CAPTCHA_KEY); String captchaCode = parameters.get(CaptchaConstant.CAPTCHA_CODE); // 获取验证码 String redisCode = (String)redisTemplate.opsForValue().get(CaptchaConstant.IMAGE_CAPTCHA_KEY + captchaKey); // 判断验证码 if (captchaCode == null || !captchaCode.equalsIgnoreCa(redisCode)) { throw new UrDeniedAuthorizationException(ResultCodeEnum.INVALID_CAPTCHA.getMsg()); } } el { // 滑动验证码验证 String captchaVerification = parameters.get(CaptchaConstant.CAPTCHA_VERIFICATION); CaptchaVO captchaVO = new CaptchaVO(); captchaVO.tCaptchaVerification(captchaVerification); ResponModel responModel = captchaService.verification(captchaVO); if (null == responModel || !RepCodeEnum.SUCCESS.getCode().equals(responModel.getRepCode())) { throw new UrDeniedAuthorizationException(ResultCodeEnum.INVALID_CAPTCHA.getMsg()); } } String phoneNumber = parameters.get(TokenConstant.PHONE_NUMBER); String smsCode = parameters.get(TokenConstant.SMS_CODE); String code = parameters.get(TokenConstant.CODE); // Protect from downstream leaks of password parameters.remove(TokenConstant.CODE); Result<Boolean> checkResult = smsFeign.checkSmsVerificationCode(smsCode, phoneNumber, code); if (null == checkResult || !checkResult.getData()) { throw new InvalidGrantException(("Could not authenticate ur: " + phoneNumber)); } UrDetails urDetails = this.urDetailsService.loadUrByUrname(phoneNumber); Authentication urAuth = new UrnamePasswordAuthenticationToken(urDetails, null, urDetails.getAuthorities()); ((AbstractAuthenticationToken)urAuth).tDetails(parameters); OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest); return new OAuth2Authentication(storedOAuth2Request, urAuth); }}
2、自定义GitEggTokenGranter,支持多种token模式
/** * 自定义token */public class GitEggTokenGranter { /** * 自定义tokenGranter */ public static TokenGranter getTokenGranter(final AuthenticationManager authenticationManager, final AuthorizationServerEndpointsConfigurer endpoints, RedisTemplate redisTemplate, IUrFeign urFeign, ISmsFeign smsFeign, CaptchaService captchaService, UrDetailsService urDetailsService, String captchaType) { // 默认tokenGranter集合 List<TokenGranter> granters = new ArrayList<>(Collections.singletonList(endpoints.getTokenGranter())); // 增加验证码模式 granters.add(new CaptchaTokenGranter(authenticationManager, endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), redisTemplate, captchaService, captchaType)); // 增加短信验证码模式 granters.add(new SmsCaptchaTokenGranter(authenticationManager, endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), redisTemplate, urFeign, smsFeign, captchaService, urDetailsService, captchaType)); // 组合tokenGranter集合 return new CompositeTokenGranter(granters); }}
3、GitEggOAuthController中增加获取短信验证码的方法
@ApiOperation("发送短信验证码") @PostMapping("/sms/captcha/nd") public Result ndSmsCaptcha(@RequestBody SmsVerificationDTO smsVerificationDTO) { Result<Object> ndResult = smsFeign.ndSmsVerificationCode(smsVerificationDTO.getSmsCode(), smsVerificationDTO.getPhoneNumber()); return ndResult; }
4、前端页面增加短信验证码登录方式
<a-tab-pane key="phone_account" :tab="$t('ur.login.tab-login-mobile')" class="color:#1890ff;"> <a-form-item> <a-input size="large" type="text" :placeholder="$t('ur.login.mobile.placeholder')" v-decorator="['phoneNumber', {rules: [{ required: true, pattern: /^1[34578]d{9}$/, message: $t('ur.phone-number.required') }], validateTrigger: 'change'}]"> <a-icon slot="prefix" type="mobile" :style="{ color: '#1890ff' }" /> </a-input> </a-form-item> <a-row :gutter="16"> <a-col class="gutter-row" :span="16"> <a-form-item> <a-input size="large" type="text" :placeholder="$t('ur.login.mobile.verification-code.placeholder')" v-decorator="['captcha', {rules: [{ required: true, message: $t('ur.verification-code.required') }], validateTrigger: 'blur'}]"> <a-icon slot="prefix" type="mail" :style="{ color: '#1890ff' }" /> </a-input> </a-form-item> </a-col> <a-col class="gutter-row" :span="8"> <a-button class="getCaptcha" tabindex="-1" :disabled="state.smsSendBtn" @click.stop.prevent="getCaptcha" v-text="!state.smsSendBtn && $t('ur.register.get-verification-code') || (state.time+' s')"></a-button> </a-col> </a-row> </a-tab-pane>
getCaptcha (e) { e.preventDefault() const { form: { validateFields }, state } = this validateFields(['phoneNumber'], { force: true }, (err, values) => { if (!err) { state.smsSendBtn = true const interval = window.tInterval(() => { if (state.time-- <= 0) { state.time = 60 state.smsSendBtn = fal window.clearInterval(interval) } }, 1000) const hide = this.$message.loading('验证码发送中..', 0) getSmsCaptcha({ phoneNumber: values.phoneNumber, smsCode: 'aliLoginCode' }).then(res => { tTimeout(hide, 2500) this.$notification['success']({ message: '提示', description: '验证码获取成功,您的验证码为:' + res.result.captcha, duration: 8 }) }).catch(err => { tTimeout(hide, 1) clearInterval(interval) state.time = 60 state.smsSendBtn = fal this.requestFailed(err) }) } }) }, stepCaptchaSuccess () { this.loginSuccess() }, stepCaptchaCancel () { this.Logout().then(() => { this.loginBtn = fal this.stepCaptchaVisible = fal }) },
5、通过短信验证码登录界面
本文发布于:2023-02-28 21:05:00,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/167772339698610.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:missing or invalid captcha.doc
本文 PDF 下载地址:missing or invalid captcha.pdf
留言与评论(共有 0 条评论) |