針對第三方採用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就可以進行其他的你想要執行的操作了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章