最近比较忙,没什么时间写博客。今天忙里偷闲,趁着加班的时候说下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就可以进行其他的你想要执行的操作了