我們系統集成了短信通知服務,這里我們進行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,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/167772339698610.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
本文word下載地址:missing or invalid captcha.doc
本文 PDF 下載地址:missing or invalid captcha.pdf
| 留言與評論(共有 0 條評論) |