{
  "slug": "Why-does-every-developer-need-to-have-knowledge-about-Workers-in-Cloudflare--9f8728a6e243",
  "title": "Why does every developer need to have knowledge about Workers in Cloudflare?",
  "subtitle": "Cloudflare is not only the biggest CDN in the world but it has very interesting facilities about infrastructure. One of these technologies…",
  "excerpt": "Cloudflare is not only the biggest CDN in the world but it has very interesting facilities about infrastructure. One of these technologies…",
  "date": "2023-05-10",
  "tags": [],
  "readingTime": "5 min",
  "url": "https://medium.com/@mobinshaterian/why-does-every-developer-need-to-have-knowledge-about-workers-in-cloudflare-9f8728a6e243",
  "hero": "https://cdn-images-1.medium.com/max/800/1*Aiqs6qj24SZnoibGIzkXPw.png",
  "content": [
    {
      "type": "paragraph",
      "html": "Cloudflare is not only the biggest CDN in the world but it has very interesting facilities about infrastructure. One of these technologies behind Cloudflare is Workers."
    },
    {
      "type": "paragraph",
      "html": "Workers are serverless computing platforms, which means that we can run some code exactly on the edge of applications on our endpoints. before requests are received for our application we can make the decision for the requests."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*Aiqs6qj24SZnoibGIzkXPw.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 857,
      "height": 489
    },
    {
      "type": "paragraph",
      "html": "In big companies, we have a DevOps role and they can set edge servers only for configuration access points to our application but small and middle companies don’t have enough resources or they don’t have reliable DevOps engineers, so they needed some useful facilities such as worker to handel their request in short times."
    },
    {
      "type": "paragraph",
      "html": "Serverless computing is a method of providing backend services on an as-used basis. Servers are still used, but a company that gets backend services from a serverless vendor is charged based on usage, not a fixed amount of bandwidth or number of servers."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Cloudflare Workers"
    },
    {
      "type": "paragraph",
      "html": "Cloudflare has very nice documentation. I will explain some parts of this documentation too."
    },
    {
      "type": "paragraph",
      "html": "As a developer handling <strong>CORS</strong> is sometimes hard work and needs to have a separate gateway and handle the router but it can be handled by a worker in Cloudflare easily."
    },
    {
      "type": "paragraph",
      "html": "In sample exmple you can see the code for <strong>CORS header proxy.</strong>"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "List of website that use Cloudflare worker:"
    },
    {
      "type": "paragraph",
      "html": "Also, big companies used the Cloudflare worker."
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Step by Step to set a CloudFlare Wroker:"
    },
    {
      "type": "paragraph",
      "html": "Workers prepared for any situation that I can’t explain all of them in this essay. Firstly it is necessary to buy a <strong>domain</strong> and <strong>host</strong>, which means that serverless technology can’t handle any things but it has many advantages for being on the edge of application. And also it is necessary to have a real <strong>email</strong> to manage the account on Cloudflare."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*YCUMsyGBY-CQxRRjAKSpcw.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 840,
      "height": 522
    },
    {
      "type": "paragraph",
      "html": "In the worker, part can manager workers and create router for them and route your application to the worker."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*RL-Bt-d1okJ40q-Njyqleg.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 1091,
      "height": 686
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Add worker for redirect to your own website"
    },
    {
      "type": "paragraph",
      "html": "By the below command, it is very easy to make a proxy. For example, when calling the worker ( xxx.worker.dev) URL, it will fetch your website data."
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*emASgzdMsn-oGgSgzqCK2A.png",
      "alt": "Default code of Cloudflare Worker",
      "caption": "Default code of Cloudflare Worker",
      "width": 756,
      "height": 603
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "addEventListener(\"fetch\", event => {\n  let url = new URL(event.request.url);\n  url.hostname = \"your-domain\";\n  url.protocol = \"https\";\n  let request = new Request(url, event.request);\n  event.respondWith(fetch(request))\n})"
    },
    {
      "type": "paragraph",
      "html": "When called the below ULR you can flow my api:"
    },
    {
      "type": "code",
      "lang": "text",
      "code": "https://proxy-glitter-c6f6.Name6260.workers.dev/api/send.json"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*rXETFkkCTXpJCquR4-Lj_g.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 1363,
      "height": 797
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Authentication with the header"
    },
    {
      "type": "paragraph",
      "html": "This is a very useful example inside of Cloudflare. We want access to very specific endpoints on the internet for some developers without doing very special on our application."
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "export default {\n  async fetch(request) {\n    /** * @param {\n      string\n    }\n    PRESHARED_AUTH_HEADER_KEY Custom header to check for key * @param {\n      string\n    }\n    PRESHARED_AUTH_HEADER_VALUE Hard coded key value */ const PRESHARED_AUTH_HEADER_KEY =\n    \"X-Custom-PSK\";\n    const PRESHARED_AUTH_HEADER_VALUE = \"mypresharedkey\";\n    const psk = request.headers.get(PRESHARED_AUTH_HEADER_KEY);\n    if (psk === PRESHARED_AUTH_HEADER_VALUE) {\n      // Correct preshared header key supplied.Fetch request from origin.\n      return fetch(request);\n    }\n    // Incorrect key supplied.Reject the request.\n    return new Response(\"Sorry, you have supplied an invalid key.\", {\n      status: 403,\n    });\n  },\n};"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Basic Authentication with the header"
    },
    {
      "type": "paragraph",
      "html": "This example like the previous one is very useful for unpersistance access to very special people."
    },
    {
      "type": "code",
      "lang": "javascript",
      "code": "/** * Shows how to restrict access using the HTTP Basic schema.* @see\nhttps://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication *\n@see https://tools.ietf.org/html/rfc7617 * * A user-id containing a colon (\":\") character is\ninvalid, as the * first colon in a user-pass string separates user and password.*/\nexport default {\n  async fetch(request) {\n    const BASIC_USER = \"admin\";\n    const BASIC_PASS = \"admin\";\n    /** * Throws exception on verification failure.* @param {\n      string\n    }\n    user * @param {\n      string\n    }\n    pass * @throws {\n      UnauthorizedException\n    }\n    */ async function verifyCredentials(user, pass) {\n      if (BASIC_USER !== user) {\n        throw new UnauthorizedException(\"Invalid credentials.\");\n      }\n      if (BASIC_PASS !== pass) {\n        throw new UnauthorizedException(\"Invalid credentials.\");\n      }\n    }\n    /** * Parse HTTP Basic Authorization value.* @param {\n      Request\n    }\n    request * @throws {\n      BadRequestException\n    }\n    * @returns {\n      {\n        user: string, pass: string\n      }\n    }\n    */ async function basicAuthentication(request) {\n      const Authorization = request.headers.get(\"Authorization\");\n      const [scheme, encoded] = Authorization.split(\"\n    \");\n      // The Authorization header must start with Basic, followed by a space.\n      if (!encoded || scheme !== \"Basic\") {\n        throw new BadRequestException(\"Malformed authorization header.\");\n      }\n      // Decodes the base64 value and performs unicode normalization.//\n      @see https://datatracker.ietf.org/doc/html/rfc7613#section-3.3.2 (and #section-4.2.2) //\n      @see https://dev.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/normalize\n      const buffer = Uint8Array.from(atob(encoded), (character) => character.charCodeAt(0));\n      const decoded = new TextDecoder().decode(buffer).normalize();\n      // The username & password are split by the first colon.//=> example: \"username:password\"\n      const index = decoded.indexOf(\":\");\n      // The user & password are split by the first colon and MUST NOT contain control characters.//\n      @see https://tools.ietf.org/html/rfc5234#appendix-B.1 (=> \"CTL = %x00-1F / %x7F\")\n      if (index === -1 || /[\\0-\\x1F\\x7F]/.test(decoded)) {\n        throw new BadRequestException(\"Invalid authorization value.\");\n      }\n      return {\n        user: decoded.substring(0, index), pass: decoded.substring(index + 1),\n      };\n    }\n    async function UnauthorizedException(reason) {\n      this.status = 401;\n      this.statusText = \"Unauthorized\";\n      this.reason = reason;\n    }\n    async function BadRequestException(reason) {\n      this.status = 400;\n      this.statusText = \"Bad Request\";\n      this.reason = reason;\n    }\n    const {\n      protocol, pathname\n    }\n    = new URL(request.url);\n    // In the case of a Basic authentication, the exchange MUST happen over an HTTPS (TLS)\n    connection to be secure.\n    if (\"https:\" !== protocol || \"https\" !== request.headers.get(\"x-forwarded-proto\")) {\n      throw new BadRequestException(\"Please use a HTTPS connection.\");\n    }\n    switch (pathname) {\n      case \"/\": return new Response(\"Anyone can access the homepage.\");\n      case \"/logout\": // Invalidate the \"Authorization\" header by returning a HTTP 401.// We do not\n      send a \"WWW-Authenticate\" header, as this would trigger // a popup in the browser, immediately\n      asking for credentials again.\n      return new Response(\"Logged out.\", {\n        status: 401\n      });\n      case \"/admin\": {\n        // The \"Authorization\" header is sent when authenticated.\n        if (request.headers.has(\"Authorization\")) {\n          // Throws exception when authorization fails.\n          const {\n            user, pass\n          }\n          = basicAuthentication(request);\n          verifyCredentials(user, pass);\n          // Only returns this response when no exception is thrown.\n          return new Response(\"You have private access.\", {\n            status: 200, headers: {\n              \"Cache-Control\": \"no-store\",\n            },\n          });\n        }\n        // Not authenticated.\n        return new Response(\"You need to login.\", {\n          status: 401, headers: {\n            // Prompts the user for credentials.\"WWW-Authenticate\":\n            'Basic realm=\"my scope\", charset=\"UTF-8\"',\n          },\n        });\n      }\n      case \"/favicon.ico\": case \"/robots.txt\": return new Response(null, {\n        status: 204\n      });\n    }\n    return new Response(\"Not Found.\", {\n      status: 404\n    });\n  },\n};"
    },
    {
      "type": "heading",
      "level": 2,
      "text": "Pictures of workers"
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*MVdjyevZ0UaM-zK9dcoOCg.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 1102,
      "height": 356
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*IByqyUJM47y9-7exZT1NjQ.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 898,
      "height": 175
    },
    {
      "type": "image",
      "src": "https://cdn-images-1.medium.com/max/800/1*i8x9XSH1ymkQSDMC7Obzzg.png",
      "alt": "Why does every developer need to have knowledge about Workers in Cloudflare?",
      "caption": "",
      "width": 758,
      "height": 186
    }
  ]
}
