自建免費圖床, 免費資源利用 onedriver api 自建圖床


免費圖床, 都推薦的比較穩定的

推薦看 這里, 已經總結了 免費圖床點這里

用別人的不放心, 對接api 不靈活, 自己需求主要也是做站

提供一個思路, 使用onedriver 或 google driver api 自建免費圖床

cocook免費圖床

  • 要求, 當然要回簡單的編碼, 是什么語言無所謂
  • 有服務器, 最基礎配置就行了
  • 看懂 oneDriver api, 現在老的api授權已經不好用, 推薦直接用最新的 建立
  • 注冊clintid 地址 注冊點這里
  • api 地址, 主要是 授權(使用auth2 最新版) 上傳 下載 api點這里
  • 由於 微軟大廠, api太多, 也花費了 兩天時間 才對接完成, 建議使用最新的api

下面 介紹一下 具體的 流程

1. 授權 auth2, 授權地址, 中文叫什么 終結點url, 看這個就知道了

注意 scope 權限 , redirect_uri 授權成功跳轉地址, 獲取code, 所有的 auth2 都是這個流程

	
	public String getAuthUrl(Map<String, String> params0){
		String url = Constants.get("login_url") +"/authorize";
			url += "?client_id=" + Constants.get("client_id");
			url += "&response_type=code";
			url += "&redirect_uri=" + Constants.get("redirect_uri");
			url += "&scope=offline_access%20Files.ReadWrite.All%20Sites.Read.All%20User.Read";
			
		return url;
	}

2. 獲取code后, 使用code 獲取 access_token, 其中需要用到密鑰

code是上面獲取到的, 注意 redirect_uri 相同 , client_secret 密鑰, 在建立clientid的地方
獲取到 access_token- 用於api請求的token, expires_in - token過期時間緩存一下, refresh_token-刷新token 用的

	
	public String getToken(Map<String, String> params0){
		String code = params0.get("code");
		String url = Constants.get("login_url") +"/token";
		HashMap<String, String> params = new HashMap<>();
		params.put("client_id", Constants.get("client_id"));
		params.put("redirect_uri", Constants.get("redirect_uri"));
		params.put("client_secret", Constants.get("client_secret"));
		params.put("code", code);
		params.put("grant_type", "authorization_code");
		Map<String, Object> resp =  OKHttpUtil.post(url, params);;
		LogUtil.info("getToken->" + resp);
		String token = (String) resp.get("access_token");
		int expires_in = (int) resp.get("expires_in") ;
		VcodeUtil.timedCache.put("access_token", token, expires_in* 1000);
		String refresh_token = (String) resp.get("refresh_token");
		VcodeUtil.timedCache.put("refresh_token", refresh_token, expires_in* 1000 * 36);
		return token;
	}

3. 使用 refresh_token 刷新 access_token,建緩存過期時間

緩存 access_token 3600秒, 失效后使用 refresh_token 刷新 access_token , refresh_token的 時效較長, 微軟沒有指定具體多久,
測試 至少在 天級別以上

	
	public String getTokenByCache(Map<String, String> params0){
		String token = (String) VcodeUtil.timedCache.getNotUpLastAccess("access_token");
		if (token != null) {
			return token;
		}
		
		String refresh_token = (String) VcodeUtil.timedCache.getNotUpLastAccess("refresh_token");
		String url = Constants.get("login_url") +"/token";
		
		HashMap<String, String> params = new HashMap<>();
		params.put("client_id", Constants.get("client_id"));
		params.put("scope", "offline_access Files.ReadWrite.All Sites.Read.All User.Read");
		params.put("refresh_token", refresh_token);
		params.put("redirect_uri", Constants.get("redirect_uri"));
		params.put("client_secret", Constants.get("client_secret"));
		params.put("grant_type", "refresh_token");
		Map<String, Object> resp =  OKHttpUtil.post(url, params);;
		LogUtil.info("getToken->" + resp);
		token = (String) resp.get("access_token");
		int expires_in = (int) resp.get("expires_in") ;
		VcodeUtil.timedCache.put("access_token", token, expires_in* 1000);
		refresh_token = (String) resp.get("refresh_token");
		VcodeUtil.timedCache.put("refresh_token", refresh_token, expires_in* 1000 * 36);
		return token;
	}

4. 使用 access_token 上傳文件, 使用簡易api, 只支持 4M的文件, 如果是大文件的話, 還是用以前推薦的一些工具吧

//PUT /me/drive/items/{parent-id}😕{filename}:/content , 上傳地址很費解, 這里我做了例子
這樣好理解一點, 使用 絕對路徑上傳, body 直接是文件流
/SEARCH_APP/upload/201912/10/Q5pe5A.jpg 這里是文件路勁
https://graph.microsoft.com/v1.0/me/drive/root:/SEARCH_APP/upload/201912/10/Q5pe5A.jpg:/content
上傳成功后 會返回 這個 item 的信息, 里面有下載地址, 保存這個 id, 和 路徑, 下載的時候提供 itemid 下載方式 和路徑方式

	
	public String upload(String uploadPath, String suffix, ByteArrayOutputStream out) throws Exception{
		byte[] bytes = out.toByteArray();
		
		long id = MD5.md5_long(bytes);
		Map<String, Object> ins = getIns(id);
		if(!ins.isEmpty()) {
			return (String) ins.get("itemid");
		}
		
		String date = BaseUtil.getFormatDate().replaceFirst("/", "");
		uploadPath += date;
		String filename = uploadPath + "/" + RandomStringUtils.randomAlphanumeric(6) +"." + suffix;
		//PUT /me/drive/items/{parent-id}:/{filename}:/content
		String url = "https://graph.microsoft.com/v1.0/me/drive/root:" + filename +":/content";
		HttpRequest request = new HttpRequest(url, Method.put);
		request.setContentType("image/jpeg");
		request.addHeader("Authorization", "Bearer " + getTokenByCache(null));
		request.setRequestBody(bytes);
		HttpResponse res =  OKHttpUtil.request(request);
		// 返回的 id 就是 itemid, 可以用此id做一些操作 保存itemid 和 filePath
		String resStr=  res.getResponseString();
		Map<String, Object> resMap =  (Map<String, Object>) OKHttpUtil.deserialize(resStr);
		String itemid = (String) resMap.get("id");
		
		return itemid;
	}
	

5. 使用 access_token 下載文件, 使用itemid 或 文件路徑都可以

String url = "https://graph.microsoft.com/v1.0/me/drive/items/"+itemid+"/content"; // 下載 按itemid
String url = "https://graph.microsoft.com/v1.0/me/drive/root:" + filepath +":/content"; // 按文件路勁
看代碼, 上面 帶了注釋, 下載地址, 預覽地址, 和分享地址, 具體實現 看 oneApi, 我都測試過
成功請求后會出現 302 跳轉, 一般 httpclient 都會自己跳, 不想跳的找配置 獲取Location 可以查看地址

	
		public Object downLoad(Map<String, String> params) throws Exception{
		String itemid = params.get("id");
//		String url = "https://graph.microsoft.com/v1.0/me/drive/root:" + filepath +":/content"; // 按文件路勁
//		String url = "https://graph.microsoft.com/v1.0/me/drive/items/01RHKEMNKSNBGOHRSDPBHJI43LRLM62MV7/preview";  // 預覽按itemid
//		String url = "https://graph.microsoft.com/v1.0/me/drive/items/01RHKEMNKSNBGOHRSDPBHJI43LRLM62MV7/createLink"; // 分享按itemid
		String url = "https://graph.microsoft.com/v1.0/me/drive/items/"+itemid+"/content";  // 下載 按itemid
		HttpRequest request = new HttpRequest(url, Method.get);
		request.addHeader("Authorization", "Bearer " + getTokenByCache(null));
		//request.setContentType("application/json");
		//request.setRequestBody("{\"chromeless\":\"true\"}".getBytes());
		HttpResponse resp =  OKHttpUtil.request(request);
//		System.out.println(resp.getResponseString());
//		System.out.println(resp.getHeader("Location"));  // 302 跳轉, 自動重新獲取圖片 URL
		return resp.getRespInputsStream();
	}
	

6. 到這里就完成了, 由於每次都要下載, 自己做個瀏覽器緩存, 再加上 cloudflare cdn, 使用起來還行

cocook圖床

https://search.cocook.cn/archives/img/01RHKEMNL2P7NZ7CHZSVDYGGC5PLMZWPUE

開開車, 注意打開方式 github


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM