文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

基于OAuth2.0授权系统的验证码功能的实现

2024-04-02 19:55

关注

前言:

前一阵子,我自己一直在写一套后台管理系统《hanxiaozhang 后台管理系统》,后台技术栈基于SpringCloud组件实现的,授权则是使用的OAuth2.0。为了让系统的功能更加健全,我在系统内添加了验证码功能,具体实现如下:

正文:

我这套系统授权基于OAuth2.0实现,登录的是http://xxxx/oauth/token获取access_token。调用其他接口时,带上access_token进行权限认证。所以我要想加验证码,需要把验证码值放到http://xxxx/oauth/token链接上传到服务器进行验证。又因为我使用了Zuul网关,作为网站的入口。我选择在使用Zuul网关的Filter过滤器进行校验验证码。

验证码我使用的是EasyCaptcha,git地址如下:https://gitee.com/whvse/EasyCaptcha。为了快速校验验证信息,我把验证码的值缓存到Redis中,具有代码实现如下:

1.集成EasyCaptcha:


<dependencies>
   <dependency>
      <groupId>com.github.whvcse</groupId>
      <artifactId>easy-captcha</artifactId>
      <version>1.6.2</version>
   </dependency>
</dependencies>

2.生成验证码并保存到Redis中:



    @GetMapping("/captcha")
    public Result captcha() {
 
        String captchaKey = "captcha_" + UUID.randomUUID();
        // 三个参数分别为宽、高、位数
        SpecCaptcha captcha = new SpecCaptcha(130, 60, 4);
        // 设置字体 有默认字体,可以不用设置
        captcha.setFont(new Font("Verdana", Font.PLAIN, 32));
        // 设置类型,纯数字、纯字母、字母数字混合
        captcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
        log.info("key: [{}] ,code: [{}]", captchaKey, captcha.text());
        // 存入Redis ,默认两分钟
        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. 校验验证码的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;
 

@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发送两次请求
            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 获取验证码:


GET http://localhost/api/system/captcha

4.2 校验验证码:


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

成功返回如下: 

过期返回如下:

错误返回如下:

 

以上就是基于OAuth2.0授权系统的验证码功能的实现的详细内容,更多关于OAuth2.0授权系统验证码的资料请关注编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯