{"id":19152706,"url":"https://github.com/rasyidf/klearn","last_synced_at":"2025-10-14T04:43:39.577Z","repository":{"id":104095473,"uuid":"437344963","full_name":"rasyidf/klearn","owner":"rasyidf","description":null,"archived":false,"fork":false,"pushed_at":"2021-12-13T02:52:29.000Z","size":194,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-01-03T18:47:20.739Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"klearn-eight.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rasyidf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-12-11T17:22:57.000Z","updated_at":"2021-12-13T06:31:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"a59cce5b-3815-417c-b7a2-ab6e1f03f6ab","html_url":"https://github.com/rasyidf/klearn","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasyidf%2Fklearn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasyidf%2Fklearn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasyidf%2Fklearn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rasyidf%2Fklearn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rasyidf","download_url":"https://codeload.github.com/rasyidf/klearn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240236360,"owners_count":19769580,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-09T08:18:53.264Z","updated_at":"2025-10-14T04:43:34.521Z","avatar_url":"https://github.com/rasyidf.png","language":"TypeScript","readme":"# Next.js Middleware and Supabase\n\n_([read the blog post about this example](https://jitsu.com/blog/supabase-nextjs-middleware))_\n\nThis app demonstrates how new Next.js 12 middleware works along supabase auth. `pages/index.tsx` \nis responsible for login logout using supabase-js lib (client side). Once user\nlogged in, it calls `pages/api/set.ts` to set a server-side cookie containing supabase JWT token.\nAfter logout, `pages/api/remove.ts` is called to clear JWT cookie\n\nEvery page inside `pages/app/` is filtered by `pages/app/_middleware.ts` \n(see [how Next.js middleware works](https://nextjs.org/docs/middleware)). Middleware validates supabase JWT token (by calling supabase\nHTTP API). If the token is absent (=cookie has not been set) or is invalid (auth expired etc), \nuser will be redirected to login page. Thus, all pages in the `/app` is accessible\nonly by authorised users\n\n## Deployment and running\n\nThe app requires `NEXT_PUBLIC_SUPABASE_URL` and `NEXT_PUBLIC_SUPABASE_KEY` environment variables to be set. Read more on Supabase Docs\nsite.\n\nRun the app with `yarn install \u0026\u0026 NEXT_PUBLIC_SUPABASE_URL=\"...\" NEXT_PUBLIC_SUPABASE_KEY=\"...\" next start`. \nOpen [localhost:3000](https://localhost:3000) to\naccess it\n\n\n## Getting user server-side\n\nSee `pages/app/hidden-page.tsx`. In there, supabase user is obtained during\nserver-side rendering. Since `pages/app/_middleware.ts` has already validated the user.\nWe don't need to verify JWT with supabase server call, we can just decode JWT\n\nHaving user on getServerSideProps we pre-build some data on server (e.g. query user settings\nfrom DB). And we will save an extra request to subapase server client-side\n\n\u003chr /\u003e\n\n\n## The bug\n\nThis project also reproduces the bug with `supabase-js` lib. See `_middleware.js`. In theory,\nif you uncomment `supabase.auth.api.getUserByCookie` and comment `getUser` the app should remain\nfunctinal. However, here's what happens:\n\n```\nAuthorization error, redirecting to login page ReferenceError: XMLHttpRequest is not defined\n    at eval (webpack-internal:///./node_modules/cross-fetch/dist/browser-ponyfill.js?d2fb:462:17)\n    at new Promise (\u003canonymous\u003e)\n    at fetch (webpack-internal:///./node_modules/cross-fetch/dist/browser-ponyfill.js?d2fb:455:12)\n    at eval (webpack-internal:///./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js?85f4:44:63)\n    at new Promise (\u003canonymous\u003e)\n    at eval (webpack-internal:///./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js?85f4:43:16)\n    at Generator.next (\u003canonymous\u003e)\n    at eval (webpack-internal:///./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js?85f4:16:71)\n    at new Promise (\u003canonymous\u003e)\n    at __awaiter (webpack-internal:///./node_modules/@supabase/gotrue-js/dist/module/lib/fetch.js?85f4:12:12)\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasyidf%2Fklearn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frasyidf%2Fklearn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frasyidf%2Fklearn/lists"}