针对第三方采用oauth2的授权方式授权处理(举例广点通)

最近比较忙,没什么时间写博客。今天忙里偷闲,趁着加班的时候说下oauth2的授权流程,主要是我的小伙伴对Oauth2不太了解,所以理解起来有点费劲。像腾讯这种大产,在给第三方授权的时候,基本上都是采用authorization_code的授权模式。包括微信也是。

我前面的很多文章都介绍了password的授权模式,对于authorization_code的授权模式介绍的比较少,下面我先来简单的介绍下authorization_code的授权流程。【这里的存储是数据库存储】

首先创建应用:这个创建应用的过程实际上就是oauth_client_details这个表里面插入了一条记录,这里会设置授权模式是authorization_code,并且制定redirect_url

CREATE TABLE `oauth_client_details` (
  `client_id` varchar(48) NOT NULL,
  `resource_ids` varchar(256) DEFAULT NULL,
  `client_secret` varchar(256) DEFAULT NULL,
  `scope` varchar(256) DEFAULT NULL,
  `authorized_grant_types` varchar(256) DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) DEFAULT NULL,
  `authorities` varchar(256) DEFAULT NULL,
  `access_token_validity` int(11) DEFAULT NULL,
  `refresh_token_validity` int(11) DEFAULT NULL,
  `additional_information` varchar(4096) DEFAULT NULL,
  `autoapprove` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

这个时候我们就得到了 client_id (app_id)和client_secrect(app_secret)。

第一步:获取code

授权地址?client_id=${cllient_id}&redirect_url=${redirect_url}

所以这里我们一般会给前端提供一个获取授权的请求

    @Override
    public String getAuthUrl(HttpServletRequest request) {
        String basePath = getBasePath(request);
        return MessageFormat.format(GdtConstant.GET_CODE_URL,GdtConstant.CLIENT_ID,basePath+GdtConstant.GET_TOKEN_REQUEST);
    }

第二步:回调地址创建,我们想要获取token,当然得回调到我们自己的请求上,这样才能通过code得到token

 @Override
    public void createToken(String code, HttpServletRequest request) {
        String basePath = getBasePath(request);
        String url = MessageFormat.format(GdtConstant.GET_TOKEN_URL,code,GdtConstant.CLIENT_ID,GdtConstant.CLIENT_SECRET,basePath+GdtConstant.GET_TOKEN_REQUEST);
        JSONObject result  = HTTPUtil.publicPost(url);
        if(result!=null){
            Integer returnCode = result.getInteger("code");
            if (returnCode==0){
                String access_token = result.getJSONObject("data").getString("access_token");
                String refresh_token = result.getJSONObject("data").getString("refresh_token");
                Integer access_tokenExp = result.getJSONObject("data").getInteger("access_token_expires_in");
                Integer refresh_tokenExp = result.getJSONObject("data").getInteger("refresh_token_expires_in");
                //账号ID
                String account_id = String.valueOf(result.getJSONObject("data").getJSONObject("authorizer_info").get("account_id"));
                String access_tokenRedisKey = applicationName+GdtConstant.REDIS_KEY+"access_token:"+account_id;
                String refresh_tokenRedisKey = applicationName+GdtConstant.REDIS_KEY+"refresh_token:"+account_id;
                redisTemplate.opsForValue().set(access_tokenRedisKey,access_token,access_tokenExp-20, TimeUnit.SECONDS);
                redisTemplate.opsForValue().set(refresh_tokenRedisKey,refresh_token,refresh_tokenExp,TimeUnit.SECONDS);

            }else{
                throw new CmsDataBackException("请求Token出错,{},信息{}",returnCode,result.getString("message"));
            }
        }else{
            throw new CmsDataBackException("请求Token出错");
        }
    }

这样基本上我们就得的我们想要的Token了,通过Token就可以进行其他的你想要执行的操作了

猜你喜欢

转载自blog.csdn.net/zhuwei_clark/article/details/105981190