基于OAuth2.0授權(quán)系統(tǒng)的驗(yàn)證碼功能的實(shí)現(xiàn)
前言:
前一陣子,我自己一直在寫一套后臺管理系統(tǒng)《hanxiaozhang 后臺管理系統(tǒng)》,后臺技術(shù)?;赟pringCloud組件實(shí)現(xiàn)的,授權(quán)則是使用的OAuth2.0。為了讓系統(tǒng)的功能更加健全,我在系統(tǒng)內(nèi)添加了驗(yàn)證碼功能,具體實(shí)現(xiàn)如下:
正文:
我這套系統(tǒng)授權(quán)基于OAuth2.0實(shí)現(xiàn),登錄的是http://xxxx/oauth/token獲取access_token。調(diào)用其他接口時(shí),帶上access_token進(jìn)行權(quán)限認(rèn)證。所以我要想加驗(yàn)證碼,需要把驗(yàn)證碼值放到http://xxxx/oauth/token鏈接上傳到服務(wù)器進(jìn)行驗(yàn)證。又因?yàn)槲沂褂昧薢uul網(wǎng)關(guān),作為網(wǎng)站的入口。我選擇在使用Zuul網(wǎng)關(guān)的Filter過濾器進(jìn)行校驗(yàn)驗(yàn)證碼。
驗(yàn)證碼我使用的是EasyCaptcha,git地址如下:https://gitee.com/whvse/EasyCaptcha。為了快速校驗(yàn)驗(yàn)證信息,我把驗(yàn)證碼的值緩存到Redis中,具有代碼實(shí)現(xiàn)如下:
1.集成EasyCaptcha:
<dependencies> <dependency> <groupId>com.github.whvcse</groupId> <artifactId>easy-captcha</artifactId> <version>1.6.2</version> </dependency> </dependencies>
2.生成驗(yàn)證碼并保存到Redis中:
/** * 驗(yàn)證碼 * * @return */ @GetMapping("/captcha") public Result captcha() { String captchaKey = "captcha_" + UUID.randomUUID(); // 三個(gè)參數(shù)分別為寬、高、位數(shù) SpecCaptcha captcha = new SpecCaptcha(130, 60, 4); // 設(shè)置字體 有默認(rèn)字體,可以不用設(shè)置 captcha.setFont(new Font("Verdana", Font.PLAIN, 32)); // 設(shè)置類型,純數(shù)字、純字母、字母數(shù)字混合 captcha.setCharType(Captcha.TYPE_ONLY_NUMBER); log.info("key: [{}] ,code: [{}]", captchaKey, captcha.text()); // 存入Redis ,默認(rèn)兩分鐘 redisBaseUtil.set(captchaKey, captcha.text(), 2, TimeUnit.MINUTES); Map<String, Object> map = new HashMap<>(4); map.put("captchaKey", captchaKey); map.put("image", captcha.toBase64()); return Result.success(map); }
3. 校驗(yàn)驗(yàn)證碼的Filter:
package com.hanxiaozhang.filter; import com.hanxiaozhang.constant.Constant; import com.hanxiaozhang.redis.util.RedisUtil; import com.hanxiaozhang.result.ResultCode; import com.hanxiaozhang.result.Result; import com.hanxiaozhang.util.JsonUtil; import com.netflix.zuul.ZuulFilter; import com.netflix.zuul.context.RequestContext; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants; import org.springframework.stereotype.Component; import javax.servlet.http.HttpServletRequest; import java.util.Map; /** * 〈一句話功能簡述〉<br> * 〈驗(yàn)證碼過濾器〉 * * @author hanxinghua * @create 2021/4/4 * @since 1.0.0 */ @Slf4j @Component public class CaptchaFilter extends ZuulFilter { @Autowired private RedisUtil redisBaseUtil; @Override public String filterType() { return FilterConstants.PRE_TYPE; } @Override public int filterOrder() { return 0; } @Override public boolean shouldFilter() { return true; } @Override public Object run() { RequestContext currentContext = RequestContext.getCurrentContext(); HttpServletRequest serverHttpRequest = currentContext.getRequest(); String uri = serverHttpRequest.getRequestURI(); if (uri.contains("/oauth/token")) { String method = serverHttpRequest.getMethod(); // 處理跨域Post發(fā)送兩次請求 if (Constant.OPTIONS.equals(method)) { return null; } Map<String, String[]> parameterMap = serverHttpRequest.getParameterMap(); String[] captchaKeys = null, captchaCodes = null; if (!parameterMap.isEmpty() && (captchaKeys = parameterMap.get("captcha_key")) != null && (captchaCodes = parameterMap.get("captcha_code")) != null) { String captchaKey = captchaKeys[0]; String captchaCode = captchaCodes[0]; log.info("Request Captcha Parameters: key: [{}] ,code: [{}]", captchaKey, captchaCode); String redisCaptchaCode = redisBaseUtil.get(captchaKey); String responseBody = null; if (redisCaptchaCode == null) { responseBody = JsonUtil.beanToJson(Result.error(ResultCode.LOGIN_CAPTCHA_EXPIRE)); } else if (!captchaCode.trim().equalsIgnoreCase(redisCaptchaCode)) { responseBody = JsonUtil.beanToJson(Result.error(ResultCode.LOGIN_CAPTCHA_ERROR)); } if (responseBody != null) { currentContext.setSendZuulResponse(false); currentContext.setResponseStatusCode(200); currentContext.getResponse().setContentType(Constant.APP_JSON_UTF_8); log.info("Response Parameters: \n [{}]", responseBody); currentContext.setResponseBody(responseBody); } } } return null; } }
4.使用,這里使用《Idea中HTTP Client請求測試工具》:
4.1 獲取驗(yàn)證碼:
GET http://localhost/api/system/captcha
4.2 校驗(yàn)驗(yàn)證碼:
POST http://localhost/api/system/oauth/token?username={{username}}&password={{password}}&grant_type=password&scope={{scope}}&client_id={{client_id}}&client_secret={{client_secret}}&captcha_key=captcha_23cacfe5-2751-44af-a34d-5e795caeb46a&captcha_code=5594
成功返回如下:
過期返回如下:
錯(cuò)誤返回如下:
以上就是基于OAuth2.0授權(quán)系統(tǒng)的驗(yàn)證碼功能的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于OAuth2.0授權(quán)系統(tǒng)驗(yàn)證碼的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java equals和=,==的區(qū)別詳細(xì)介紹
這篇文章主要介紹了java equals和=,==的區(qū)別,學(xué)習(xí)Java的朋友對equals 和== 這個(gè)概念開始使用的時(shí)候會有疑問,很難辨別如何正確使用,這里幫大家詳細(xì)講解該知識點(diǎn),希望大家能掌握,有需要的小伙伴可以參考下2016-10-10Java數(shù)據(jù)脫敏實(shí)現(xiàn)的方法總結(jié)
數(shù)據(jù)脫敏,指的是對某些敏感信息通過脫敏規(guī)則進(jìn)行數(shù)據(jù)的變形,實(shí)現(xiàn)敏感隱私數(shù)據(jù)的可靠保護(hù),本文主要是對后端數(shù)據(jù)脫敏實(shí)現(xiàn)的簡單總結(jié),希望對大家有所幫助2023-07-07java wait()/notify() 實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式詳解
這篇文章主要介紹了java wait()/notify() 實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模式詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07idea為java程序添加啟動參數(shù)的問題解析(program?arguments,vm?arguments,Envi
這篇文章主要介紹了idea為java程序添加啟動參數(shù)的問題解析(program?arguments,vm?arguments,Environment?variable)并在程序中獲取使用,本文給大家分享問題描述及解決方法,需要的朋友可以參考下2023-09-09java利用socket通信實(shí)現(xiàn)Modbus-RTU通信協(xié)議的示例代碼
這篇文章主要介紹了java利用socket通信實(shí)現(xiàn)Modbus-RTU通信協(xié)議的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04java 中動態(tài)代理(JDK,cglib)實(shí)例代碼
這篇文章主要介紹了java 中動態(tài)代理,這里介紹了JDK 動態(tài)代理與 cglib 動態(tài)代理的相關(guān)資料2017-04-042024.1.2 安裝JDK和Eclipse并配置java編譯環(huán)境的過程
這篇文章主要介紹了2024.1.2 安裝JDK和Eclipse并配置java編譯環(huán)境,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-01-01基于java.lang.IllegalArgumentException異常報(bào)錯(cuò)問題及解決
這篇文章主要介紹了基于java.lang.IllegalArgumentException異常報(bào)錯(cuò)問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03mybatisPlus 實(shí)體類與數(shù)據(jù)庫表映射關(guān)系詳解
這篇文章主要介紹了mybatisPlus 實(shí)體類與數(shù)據(jù)庫表映射關(guān)系詳解,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。2022-01-01