最近比較忙,沒什麼時間寫博客。今天忙裏偷閒,趁着加班的時候說下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就可以進行其他的你想要執行的操作了