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

前言:

前一阵子,我自己一直在写一套后台管理系统《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中:

/**
     * 验证码
     *
     * @return
     */
    @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;

/**
 * 〈一句话功能简述〉<br>
 * 〈验证码过滤器〉
 *
 * @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发送两次请求
            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授权系统验证码的资料请关注我们其它相关文章!

(0)

相关推荐

  • 使用Springboot搭建OAuth2.0 Server的方法示例

    OAuth是一个关于授权(authorization)的开放网络标准,在全世界得到广泛应用,目前的版本是2.0版. 本文对OAuth 2.0的设计思路和运行流程,做一个简明通俗的解释,主要参考材料为RFC 6749. OAuth 简介 OAuth 是由 Blaine Cook.Chris Messina.Larry Halff 及 David Recordon 共同发起的,目的在于为 API 访问授权提供一个安全.开放的标准. 基于 OAuth 认证授权具有以下特点: 安全.OAuth 与别的授

  • 微信网页授权(OAuth2.0) PHP 源码简单实现

    提要:  1. 建议对OAuth2.0协议做一个学习.  2. 微信官方文档和微信官网工具要得到充分利用.  比较简单,直接帖源代码了.其中"xxxxxxxxxx"部分,是需要依据自己环境做替换的 /** * OAuth2.0微信授权登录实现 * * @author zzy * @文件名:GetWxUserInfo.php */ // 回调地址 $url = urlencode("http://www.xxxxxxxxx.com/GetWxUserInfo.php"

  • nodejs实现OAuth2.0授权服务认证

    OAuth是一种开发授权的网络标准,全拼为open authorization,即开放式授权,最新的协议版本是2.0. 举个栗子: 有一个"云冲印"的网站,可以将用户储存在Google的照片,冲印出来.用户为了使用该服务,必须让"云冲印"读取自己储存在Google上的照片. 传统方法是,用户将自己的Google用户名和密码,告诉"云冲印",后者就可以读取用户的照片了.这样的做法有以下几个严重的缺点. "云冲印"为了后续的服务,

  • Spring Security Oauth2.0 实现短信验证码登录示例

    本文介绍了Spring Security Oauth2.0 实现短信验证码登录示例,分享给大家,具体如下: 定义手机号登录令牌 /** * @author lengleng * @date 2018/1/9 * 手机号登录令牌 */ public class MobileAuthenticationToken extends AbstractAuthenticationToken { private static final long serialVersionUID = SpringSecur

  • ASP.NET实现QQ、微信、新浪微博OAuth2.0授权登录 原创

    不管是腾讯还是新浪,查看他们的API,PHP都是有完整的接口,但对C#支持似乎都不是那么完善,都没有,腾讯是完全没有,新浪是提供第三方的,而且后期还不一定升级,NND,用第三方的动辄就一个类库,各种配置还必须按照他们约定的写,烦而且乱,索性自己写,后期的扩展也容易,看过接口后,开始以为很难,参考了几个源码之后发现也不是那么难,无非是GET或POST请求他们的接口获取返回值之类的,话不多说,这里只提供几个代码共参考,抛砖引玉了... 我这个写法的特点是,用到了Session,使用对象实例化之后调用

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

    前言: 前一阵子,我自己一直在写一套后台管理系统<hanxiaozhang 后台管理系统>,后台技术栈基于SpringCloud组件实现的,授权则是使用的OAuth2.0.为了让系统的功能更加健全,我在系统内添加了验证码功能,具体实现如下: 正文: 我这套系统授权基于OAuth2.0实现,登录的是http://xxxx/oauth/token获取access_token.调用其他接口时,带上access_token进行权限认证.所以我要想加验证码,需要把验证码值放到http://xxxx/oa

  • Android仿新浪微博oauth2.0授权界面实现代码(2)

    oauth2.0授权界面,大致流程图: 前提准备: 在新浪开放平台申请appkey和appsecret:http://open.weibo.com/. 熟悉oauth2.0协议,相关知识:http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html OAuth2的access_token接口:http://open.weibo.com/wiki/OAuth2/access_token 代码详解 大致思路如下:建立一个webview加载授权界面,授权回

  • 基于JS实现一个随机生成验证码功能

    效果展示 实现原理 1. html:一般就是一个div: <div id="code"></div> ,样式根据需求设计. 2. JS:1)将所有的验证码所用的字符放在一个字符串中 2)在这个字符串的字符个数以内,随机生成索引号 3)根据索引号查找对应字符,拼接成验证码的字符串 代码实现 HTML: <div id="code"></div> CSS: * { margin: 0; padding: 0; } div

  • Spring Cloud下基于OAUTH2认证授权的实现示例

    在Spring Cloud需要使用OAUTH2来实现多个微服务的统一认证授权,通过向OAUTH服务发送某个类型的grant type进行集中认证和授权,从而获得access_token,而这个token是受其他微服务信任的,我们在后续的访问可以通过access_token来进行,从而实现了微服务的统一认证授权. 本示例提供了四大部分: discovery-service:服务注册和发现的基本模块 auth-server:OAUTH2认证授权中心 order-service:普通微服务,用来验证认

  • Spring Security 图片验证码功能的实例代码

    验证码逻辑 以前在项目中也做过验证码,生成验证码的代码网上有很多,也有一些第三方的jar包也可以生成漂亮的验证码.验证码逻辑很简单,就是在登录页放一个image标签,src指向一个controller,这个Controller返回把生成的图片以输出流返回给页面,生成图片的同时把图片上的文本放在session,登录的时候带过来输入的验证码,从session中取出,两者对比.这位老师讲的用Spring Security集成验证码,大体思路和我说的一样,但更加规范和通用些. spring securi

  • 详解使用Spring Security OAuth 实现OAuth 2.0 授权

    OAuth 2.0 是一种工业级的授权协议.OAuth 2.0是从创建于2006年的OAuth 1.0继承而来的.OAuth 2.0致力于帮助开发者简化授权并为web应用.桌面应用.移动应用.嵌入式应用提供具体的授权流程. OAuth 2.0 is the industry-standard protocol for authorization. OAuth 2.0 supersedes the work done on the original OAuth protocol created i

  • Java开发完整短信验证码功能的全过程

    目录 前言 闲扯 使用技术 所需知识储备 实现步骤 总结 前言 现代互联网项目中,很多场景下都需要使用一种叫做验证码的技术,常用的有图片验证码,滑块验证码,短信验证码等,本文章描述的就是短信验证码的一个使用教程,从0开始完成一个验证码功能的开发. 闲扯 是不是看着导语很高大上!!! 我才不会说是因为最近不知道写啥才水的一篇文章 但是嘛,我要争取做到水文章也水的特别认真,让读者可以根据本文的教程实现验证码功能 使用技术 Java:所使用的后端技术 JSP:所使用的前端技术 阿里云短信服务:发送短信

随机推荐