如题的小屋
Fodi+Onedrive+Cloudflare= ?
2020-05-01
查看标签

本文链接:https://imrt.top/Fodi_Onedrive_Cloudflare.html
目前该方法可能失效,仅作存档用,不提供稳定性保证,建议使用 onedrive-vercel-index

成品

你可以收获到一个这样的网站

☞戳我


前言

我们都知道,市面上有各种各样的网盘列表软件,有的需要服务器的支持,而服务器又需要钱老百嫖人了可是就为了搭建个分享网盘就去买服务器显得有点亏胡言乱语那么有没有办法不用服务器,速度还能快起来的呢?!
那么本期的如题看世界就带你来学习如何白嫖微软和Cloudflare吧~


BGM起!
电脑查看左上角目录,请按照步骤一步步进行w~
另一种网盘搭建方案,可当图床

OneDrive白嫖

  1. 申请Office365 E5开发者订阅打开:https://developer.microsoft.com/zh-cn/office/dev-program
    按要求填写。

由于我这个人是个懒狗,所以注册账号你总会吧
这一步要验证手机号,所以这一步要magic工具填写发信验证码。
2.注册完后,进入https://portal.office.com/AdminPortal/Home,这个是管理页面

3.进入https://admin.onedrive.com/#v=StorageSettings
这一步可以改管理员之后的账号为5T空间,
1.png
当然本博也免费提供E5账号,可以带前缀找我要xD。
当然本博也免费提供E5账号,可以带前缀找我要xD,
当然本博也免费提供E5账号,可以带前缀找我要xD,
但貌似巨硬被嫖的有点多了
现在显示↓可能要等很久ww,所以为什么不来找我白嫖呢

由于请求量异常大,因此沙盒订阅中的 SharePoint、OneDrive 和 Exchange 预配可能需要长达一周的时间。预配完成前,你的订阅的某些功能将不可用。“示例数据包”功能暂时在所有订阅中不可用。

反代Worker搭建

当然你也可以使用你自己的VPS进行反代,然后把设置好的域名填入下一步后端里面
创建Cloudflare账号
输入 邮箱密码 后点击 Create Account,进入控制面板,新建一个Worker,注意你的邮箱,需要点击链接确认。
这一步的worker地址填入下一步的后端代码里

addEventListener('fetch', event => {
  event.respondWith(proxy(event));
});

async function proxy(event) {
  const getReqHeader = (key) => event.request.headers.get(key);

  let url = new URL(event.request.url);
  url.hostname = "填入你的OneDrive源像这样的→***-my.sharepoint.com";

  let parameter = {
    headers: {
      'Host': '填入OneDrive源,同上',
      'User-Agent': getReqHeader("User-Agent"),
      'Accept': getReqHeader("Accept"),
      'Accept-Language': getReqHeader("Accept-Language"),
      'Accept-Encoding': getReqHeader("Accept-Encoding"),
      'Connection': 'keep-alive',
      'Cache-Control': 'max-age=0'
    }
  };

  if (event.request.headers.has("Referer")) {
    parameter.headers.Referer = getReqHeader("Referer");
  }

  if (event.request.headers.has("Origin")) {
    parameter.headers.Origin = getReqHeader("Origin");
  }

  return fetch(new Request(url, event.request), parameter);
}

Fodi后端搭建

腾讯云函数当然也可以搭建的
但是我们作为老嫖客一个普通人
肯定不会去用腾讯的付费服务啦(虽然也不贵)
谁让我们是老实人老白嫖人

  1. 登录 Cloudflare 并创建 Workers
    2.打开网址,(目前该网站已失效)建议自行搭建https://github.com/vcheckzen/OneDrive_SCF,获取refresh_token,这一步请使用onmicrosoft.com邮箱和密码登录。

2.png
3.打开Worker,自己选个好听的前缀
微信图片_20200501163215.png
4.将如下代码填入。

/**
 * IS_CN: 如果为世纪互联版本,请将 0 改为 1
 * EXPOSE_PATH:暴露路径,如全盘展示请留空,否则按 '/媒体/音乐' 的格式填写
 * ONEDRIVE_REFRESHTOKEN: refresh_token
 */
const IS_CN = 0;
const EXPOSE_PATH = "/index"
const ONEDRIVE_REFRESHTOKEN = ""
const ORIGIN_URL = "***-my.sharepoint.com"    //填入你的OD地址
const PROXY_URL = "***.workers.dev"    //填入你创建的反代worker

async function handleRequest(request) {
  let requestPath
  let querySplited
  let queryString = request.url.split('?')[1]
  if (queryString) {
    querySplited = queryString.split('=')
  }
  if (querySplited && querySplited[0] === 'file') {
    const file = querySplited[1]
    const fileName = file.split('/').pop();
    requestPath = file.replace('/' + fileName, '')
    const url = await fetchFiles(requestPath, fileName)
    return Response.redirect(url, 302)
  } else {
    const { headers } = request
    const contentType = headers.get('content-type')
    let body={}
    if (contentType && contentType.includes('form')) {
      const formData = await request.formData()
      for (let entry of formData.entries()) {
        body[entry[0]] = entry[1]
      }
    }
    requestPath = body ? body['?path'] : '';
    const files = await fetchFiles(requestPath, null, body.passwd);
    return new Response(files, {
      headers: {
        'content-type': 'application/json; charset=utf-8',
        'Access-Control-Allow-Origin': '*'
      }
    })
  }
}

addEventListener('fetch', event => {
  return event.respondWith(handleRequest(event.request))
})


const clientId = [
  '4da3e7f2-bf6d-467c-aaf0-578078f0bf7c',
  '04c3ca0b-8d07-4773-85ad-98b037d25631'

]
const clientSecret = [
  '7/+ykq2xkfx:.DWjacuIRojIaaWL0QI6',
  'h8@B7kFVOmj0+8HKBWeNTgl@pU/z4yLB'
]

const oauthHost = [
  'https://login.microsoftonline.com',
  'https://login.partner.microsoftonline.cn'
]

const apiHost = [
  'https://graph.microsoft.com',
  'https://microsoftgraph.chinacloudapi.cn'
]

const OAUTH = {
  'redirectUri': 'https://scfonedrive.github.io',
  'refreshToken': ONEDRIVE_REFRESHTOKEN,
  'clientId': clientId[IS_CN],
  'clientSecret': clientSecret[IS_CN],
  'oauthUrl': oauthHost[IS_CN] + '/common/oauth2/v2.0/',
  'apiUrl': apiHost[IS_CN] + '/v1.0/me/drive/root',
  'scope': apiHost[IS_CN] + '/Files.ReadWrite.All offline_access'
}

async function gatherResponse(response) {
  const { headers } = response
  const contentType = headers.get('content-type')
  if (contentType.includes('application/json')) {
    return await response.json()
  } else if (contentType.includes('application/text')) {
    return await response.text()
  } else if (contentType.includes('text/html')) {
    return await response.text()
  } else {
    return await response.text()
  }
}

async function getContent(url) {
  const response = await fetch(url)
  const result = await gatherResponse(response)
  return result
}

async function getContentWithHeaders(url, headers) {
  const response = await fetch(url, { headers: headers })
  const result = await gatherResponse(response)
  return result
}

async function fetchFormData(url, data) {
  const formdata = new FormData();
  for (const key in data) {
    if (data.hasOwnProperty(key)) {
      formdata.append(key, data[key])
    }
  }
  const requestOptions = {
    method: 'POST',
    body: formdata
  };
  const response = await fetch(url, requestOptions)
  const result = await gatherResponse(response)
  return result
}

async function fetchAccessToken() {
  url = OAUTH['oauthUrl'] + 'token'
  data = {
    'client_id': OAUTH['clientId'],
    'client_secret': OAUTH['clientSecret'],
    'grant_type': 'refresh_token',
    'requested_token_use': 'on_behalf_of',
    'refresh_token': OAUTH['refreshToken']
  }
  const result = await fetchFormData(url, data)
  return result.access_token
}

async function fetchFiles(path, fileName, passwd) {
  if (!path || path === '/') {
    if (EXPOSE_PATH === '') {
      path = ''
    } else {
      path = ':' + EXPOSE_PATH
    }
  } else {
    if (EXPOSE_PATH === '') {
      path = ':' + path
    } else {
      path = ':' + EXPOSE_PATH + path
    }
  }

  const accessToken = await fetchAccessToken()
  const uri = OAUTH.apiUrl + encodeURI(path) + '?expand=children(select=name,size,parentReference,lastModifiedDateTime,@microsoft.graph.downloadUrl)'

  const body = await getContentWithHeaders(uri, {
    Authorization: 'Bearer ' + accessToken
  })
  if (fileName) {
    let thisFile = null
    body.children.forEach(file => {
      if (file.name === decodeURIComponent(fileName)) {
        thisFile = file['@microsoft.graph.downloadUrl']
        return
      }
    })
    return thisFile
  } else {
    let files = []
    let encrypted = false
    for (let i = 0; i < body.children.length; i++) {
      const file = body.children[i]
      if (file.name === '.password') {
        const PASSWD = await getContent(file['@microsoft.graph.downloadUrl'])
        if (PASSWD !== passwd) {
          encrypted = true;
          break
        } else {
          continue
        }
      }
      files.push({
        name: file.name,
        size: file.size,
        time: file.lastModifiedDateTime,
        url: file['@microsoft.graph.downloadUrl']
      })
    }
    let parent
    if (body.children.length) {
      parent = body.children[0].parentReference.path
    } else {
      parent = body.parentReference.path
    }
    parent = parent.split(':').pop().replace(EXPOSE_PATH, '') || '/'
    parent = decodeURIComponent(parent)
    if (encrypted) {
      return JSON.stringify({ parent: parent, files: [], encrypted: true })
    } else {
      return JSON.stringify({ parent: parent, files: files }).replace(RegExp(ORIGIN_URL,"g"),PROXY_URL)
    }
  }
}

Fodi前端搭建
Click It!

这就是一个Html文件
你可以放在Github pages
放在云虚机上,扔到服务器上都是Ok的!
至此你的网盘已经搭建好了
Enjoy it!
FODI源项目,给原作者Star吧~

版权声明:自由转载-非商用-保持署名(CC BY-NC 4.0)
评论已关闭>_<
May 16th, 2020 at 05:04 pmWhiteNX
May 16th, 2020 at 05:04 pm

学到了学到了,之后把我所有的Gal迁移上去,不然太占空间了 奥妙重重

大佬
May 16th, 2020 at 08:30 pmRt
May 16th, 2020 at 08:30 pm
@WhiteNX 

向大佬低头 记得存好后发我一份 (

蒟蒻
May 11th, 2020 at 11:12 amRoyce
May 11th, 2020 at 11:12 am

好多学习资料 :qq25:

大佬
May 11th, 2020 at 01:23 pmRt
May 11th, 2020 at 01:23 pm
@Royce 

哪里有啊,我怎么没看见( 一脸懵逼

蒟蒻
May 10th, 2020 at 06:01 pmYue
May 10th, 2020 at 06:01 pm

向大佬低头 学到了 改天可以把我的种子迁移一下

大佬
May 10th, 2020 at 08:25 pmRt
May 10th, 2020 at 08:25 pm
@Yue 

或许这就是大佬 看来种子不少啊

蒟蒻
zhou216
May 2nd, 2020 at 07:39 pmzhou216
May 2nd, 2020 at 07:39 pm

直奔游戏区
果然,不出我所料
有galgame
为什么大佬总喜欢往自己网盘放奇怪的东西

大佬
May 2nd, 2020 at 08:18 pmRt
May 2nd, 2020 at 08:18 pm
@zhou216 

gal能算奇怪的东西吗(? 一脸懵逼

蒟蒻