តើអ្នកធ្លាប់បានទទួលកញ្ចប់របស់អ្នកជិតខាងនៅទ្វារមុខរបស់អ្នកដែរឬទេ? (ប្រហែលជាសូម្បីតែបើកវាដោយចៃដន្យ?) ប្រហែលជាអ្នកបានទុកសារជាសំឡេងដ៏រសើបសម្រាប់នរណាម្នាក់ផ្សេងទៀត? ក្នុងនាមជាអ្នកបង្កើតកម្មវិធី វាជាការងាររបស់អ្នកដើម្បីធានាថាទិន្នន័យរសើបដែលបានរក្សាទុកក្នុងកម្មវិធីរបស់អ្នកមិនត្រូវបានគេបញ្ជូនដោយចៃដន្យទៅភាគីផ្សេងទេ។ មានបច្ចេកទេសជាច្រើនដែលអាចប្រើបានដើម្បីរក្សាទុកទិន្នន័យរបស់អតិថិជនដោយសុវត្ថិភាព ហើយជាច្រើនមានភាពស្មុគស្មាញខ្ពស់និងពិបាកក្នុងការអនុវត្ត។ តាមឧត្ដមគតិ មនុស្សម្នាក់អាចធានាបាននូវទិន្នន័យអតិថិជនទាំងអស់នៅក្នុងមូលដ្ឋានទិន្នន័យតែមួយ - រក្សាការរចនានៃលក្ខណៈពិសេសនេះសាមញ្ញ និងមានសុវត្ថិភាព។ គឺជាសមត្ថភាពធានាសុវត្ថិភាព និងគ្រប់គ្រងការចូលទៅកាន់ជួរទិន្នន័យជាក់លាក់ក្នុងតារាងមូលដ្ឋានទិន្នន័យ។ វាគឺជាឧបករណ៍ដ៏មានឥទ្ធិពលដែលអនុញ្ញាតឱ្យអ្នករក្សាទុកទិន្នន័យអតិថិជនរបស់អ្នកទាំងអស់នៅក្នុងមូលដ្ឋានទិន្នន័យតែមួយដោយគ្មានការព្រួយបារម្ភអំពីការលេចធ្លាយទិន្នន័យនៅលើគណនី។ ទោះជាយ៉ាងណាក៏ដោយ ការអនុវត្ត RLS យ៉ាងត្រឹមត្រូវអាចជាដំណើរការដ៏លំបាកមួយដែលពាក់ព័ន្ធនឹងការរួមបញ្ចូលព័ត៌មានលម្អិតនៃការចូលជាមួយនឹងការអនុញ្ញាតមូលដ្ឋានទិន្នន័យរបស់អ្នក។ សម្រួលដំណើរការនេះដោយបញ្ចូលការផ្ទៀងផ្ទាត់ដោយស្វ័យប្រវត្តិពីអ្នកផ្តល់សេវា OAuth របស់អ្នកជាមួយនឹងមូលដ្ឋានទិន្នន័យ PostgreSQL របស់អ្នក។ Row-level security (RLS) Neon Authorize Neon Authorize ប្រើប្រាស់ស្រទាប់ផ្ទៀងផ្ទាត់ដែលមានស្រាប់របស់អ្នកដើម្បីកំណត់អត្តសញ្ញាណរាល់អ្នកប្រើប្រាស់ដែលបានចូល និងភ្ជាប់ទិន្នន័យទាំងអស់នៅក្នុងមូលដ្ឋានទិន្នន័យរបស់អ្នកជាមួយនឹងព័ត៌មានសម្ងាត់នៃការចូលរបស់ពួកគេ។ នេះធានាថាទិន្នន័យដែលបានរក្សាទុកក្នុងមូលដ្ឋានទិន្នន័យអាចចូលប្រើបានតែដោយអ្នកប្រើប្រាស់ដែលបានចូលប៉ុណ្ណោះ ហើយមានតែអ្នកប្រើប្រាស់ដែលបានចូលប៉ុណ្ណោះអាចឃើញទិន្នន័យរបស់ពួកគេបាន។ ការបង្រៀននេះនឹងណែនាំអ្នកពីរបៀបបង្កើតកម្មវិធី Remix ដោយប្រើ Clerk ជាស្រទាប់ផ្ទៀងផ្ទាត់។ គឺជាឧបករណ៍ផ្ទៀងផ្ទាត់ និងគ្រប់គ្រងអ្នកប្រើប្រាស់ដ៏ពេញនិយម។ អ្នកនឹងប្រើ Neon Postgres ជាស្រទាប់ទិន្នន័យរបស់អ្នក ហើយប្រើប្រាស់ Neon Authorize ដើម្បីការពារទិន្នន័យទាំងអស់សម្រាប់អតិថិជនដែលបានចូលនីមួយៗ។ ជួរនីមួយៗក្នុងតារាងនឹងកំណត់អត្តសញ្ញាណអ្នកប្រើប្រាស់ ដែលត្រូវបានផ្តល់ដោយស្មៀន។ មានតែអ្នកដែលបានផ្ទៀងផ្ទាត់ជាមួយ userID ប៉ុណ្ណោះដែលអាចធ្វើអន្តរកម្មជាមួយទិន្នន័យក្នុងជួរបាន។ ស្មៀន កម្មវិធីគំរូរបស់យើងគឺសាមញ្ញ - វាកត់ត្រារាល់ការចូលចូលទៅក្នុងមូលដ្ឋានទិន្នន័យ RLS ដោយប្រើលេខសម្គាល់អ្នកប្រើប្រាស់។ នៅពេលដែលទំព័រត្រូវបានផ្ទុក ការចូលចំនួន 10 ចុងក្រោយសម្រាប់អ្នកប្រើប្រាស់ដែលបានផ្ទៀងផ្ទាត់នឹងត្រូវបានបង្ហាញ ហើយគ្មានទិន្នន័យរបស់អ្នកប្រើផ្សេងទៀត (រក្សាទុកក្នុងតារាង PostgreSQL ដូចគ្នា) នឹងលេចឡើង។ តោះចាប់ផ្តើម! ការបង្កើតកម្មវិធី Remix ចាប់ផ្តើមដោយបង្កើតកម្មវិធី Remix និងដំឡើងភាពអាស្រ័យដោយប្រើអត្ថបទកូដខាងក្រោម។ សម្រាប់ការណែនាំលម្អិតបន្ថែម សូមមើល ។ ការណែនាំអំពីការចាប់ផ្តើមរហ័ស Remix ##make a directory and initialise your NPM project mkdir neon-authorize-remix-clerk-app cd neon-authorize-remix-clerk-app npm init -y ## install runtime dependecies for Remix npm i @remix-run/node @remix-run/react @remix-run/serve isbot@4 react react-dom @remix-run/router drizzle-orm npm install @neondatabase/serverless npm install @clerk/remix npm i -D @remix-run/dev vite ចាប់តាំងពី Remix ប្រើ Vite ដែលជាឧបករណ៍បង្កើត Javascript បង្កើត នៅក្នុងថត root៖ vite.config.js import { vitePlugin as remix } from "@remix-run/dev"; import { defineConfig } from "vite"; export default defineConfig({ plugins: [remix()], }); មុននឹងធ្វើការអភិវឌ្ឍន៍ណាមួយ យើងត្រូវបង្កើតគណនីនៅ Clerk និង Neon ដើម្បីប្រើប្រាស់សេវាកម្មរបស់ពួកគេ៖ ការបង្កើតករណីស្មៀន និងណេអុង ស្មៀន ចូលទៅផ្ទាំងគ្រប់គ្រងស្មៀន ដើម្បីបង្កើតគម្រោងថ្មី។ នៅក្នុងការរុករកខាងឆ្វេង សូមជ្រើសរើស ។ API Keys នៅក្នុងប្រអប់ Quick Copy ជ្រើសរើស Remix ហើយចម្លងអថេរបរិស្ថាន។ បិទភ្ជាប់ពួកវាទៅក្នុងឯកសារ នៅក្នុងកូដរបស់អ្នក។ .env នៅក្នុងការរុករកខាងឆ្វេង ជ្រើសរើស “ ” គំរូ JWT ។ បង្កើតគំរូមួយ (ខ្ញុំដាក់ឈ្មោះខ្ញុំថា " ")។ neon-remix ចម្លង សម្រាប់ប្រើពេលក្រោយ។ JWKS Endpoint URL អ៊ីយូន ចូលទៅក្នុងកុងសូល Neon ហើយបង្កើតគម្រោងថ្មីមួយ។ ពីម៉ឺនុយរុករកខាងឆ្វេង សូមជ្រើសរើស ។ អនុញ្ញាត បង្កើតអ្នកផ្តល់សេវាថ្មី ហើយបិទភ្ជាប់ ដែលអ្នកបានចម្លងពីស្មៀនមុន។ Clerk JWKS URL នៅពេលអ្នកបានបង្កើតឧទាហរណ៍សូមចុច "ចាប់ផ្តើម" ។ បន្ទះចំហៀងនឹងបើកជាមួយនឹងជំហានជាច្រើនដើម្បីបញ្ចប់ការរួមបញ្ចូល Neon Authorize របស់អ្នក។ ការដំឡើងចាប់ផ្តើមផ្តល់ឱ្យអ្នកនូវជំហានដើម្បីរៀបចំគម្រោងផ្តល់សិទ្ធិជាមូលដ្ឋានជាមួយស្មៀន។ 1. Set up Neon Extension and Roles Privileges. Run these steps in the Dashboard. 2. Grant privileges to the roles in the neondb database. ការដំឡើងសុវត្ថិភាពកម្រិតជួរដេក លេខកូដដែលបានផ្តល់គឺសម្រាប់កម្មវិធី todos ។ ជំនួសឱ្យការប្រើប្រាស់កូដ boilerplate ដែលបានផ្តល់ឱ្យពី Neon សម្រាប់កម្មវិធី todos យើងនឹងបង្កើតតារាង ហើយដំឡើង RLS នៅលើវា។ បើក SQL Editor នៅក្នុងផ្ទាំងគ្រប់គ្រង Neon ហើយដំណើរការកូដខាងក្រោម។ តារាង នឹងត្រូវបានប្រើដើម្បីទុកពេលចូលសម្រាប់អ្នកប្រើនីមួយៗ។ login_history login_history ចំណាំថា មានជួរឈរបីប៉ុណ្ណោះ៖ លេខសម្គាល់ អ្នកប្រើប្រាស់_id និងចូល_at។ ជួរឈរពីរចុងក្រោយនឹងបង្ហាញការចូលថ្មីៗបំផុតនៅក្នុងកម្មវិធី។ login_history CREATE TABLE login_history ( id bigint generated by default as identity primary key, user_id text not null default (auth.user_id()), login_at timestamp not null default now() ); -- 1st enable row level security for your table ALTER TABLE login_history ENABLE ROW LEVEL SECURITY; -- 2nd create policies for your table CREATE POLICY "Individuals can add login." ON login_history FOR INSERT TO authenticated WITH CHECK ((select auth.user_id()) = user_id); CREATE POLICY "Individuals can view their own logins. " ON login_history FOR SELECT TO authenticated USING ((select auth.user_id()) = user_id); បន្ថែមអថេរបរិស្ថានដែលបានផ្តល់ទៅ របស់អ្នក។ .env នៅពេលដែលជំហានដំឡើងទាំងនេះត្រូវបានបញ្ចប់ របស់អ្នកគួរតែមានអថេរចំនួនបួន៖ ពីរពីស្មៀន និងពីរពីណេអុង៖ .env CLERK_PUBLISHABLE_KEY=pk_test_.... CLERK_SECRET_KEY=sk_test_... # Database owner connection string DATABASE_URL='postgresql://neondb_owner:...' # Neon "authenticated" role connection string DATABASE_AUTHENTICATED_URL='postgresql://authenticated@ep-... បង្កើតកម្មវិធី Remix ឥឡូវនេះកម្មវិធីបានត្រៀមខ្លួនជាស្រេចដើម្បីត្រូវបានបង្កើតឡើង។ កូដពេញលេញមាននៅលើ ប៉ុន្តែមុខងារសំខាន់ៗបំផុតត្រូវបានរំលេចនៅទីនេះ។ ស្នូលនៃកម្មវិធីគឺនៅក្នុង ៖ GitHub app/routes/_index.tsx export const loader: LoaderFunction = async (args) => { const { userId, getToken } = await getAuth(args); if (!userId) { return redirect("/sign-in"); } const authToken = await getToken(); console.log(userId); if (!authToken) { return null; } const DATABASE_AUTHENTICATED_URL= process.env.NEXT_PUBLIC_DATABASE_AUTHENTICATED_URL; try { const sql = neon(DATABASE_AUTHENTICATED_URL ?? '', { authToken, }); const loginResponse = await sql(`INSERT INTO login_history ("user_id") VALUES ($1) RETURNING *`,[userId]); // Retrieve last 10 logins const last10LoginsResponse = await sql(`SELECT * FROM login_history WHERE user_id = $1 ORDER BY login_at DESC LIMIT 10`, [userId]); console.log(`loginResponse: ${JSON.stringify(loginResponse)}`); return last10LoginsResponse as Array<LoginHistory>; } catch (error) { console.error(`Error inserting into login_history table: ${error.message}`); console.error(`Error details: ${JSON.stringify(error)}`); throw error; } } មុខងារ នៅក្នុងឯកសារ បំពេញភារកិច្ចនៅលើម៉ាស៊ីនមេ មុនពេលបង្ហាញទំព័រសម្រាប់អតិថិជន។ នៅក្នុងកម្មវិធីនេះ កម្មវិធី loader ធ្វើការលើកច្រើននៃកម្មវិធី។ LoaderFunction _index.tsx មុខងារដំបូងពិនិត្យមើលថាតើអ្នកប្រើប្រាស់មិនបានចូល ហើយបន្ទាប់មកបញ្ជូនអ្នកប្រើប្រាស់ទៅកាន់ទំព័រ ។ ទំព័រចូលអាចត្រូវបានកំណត់រចនាសម្ព័ន្ធនៅក្នុងផ្ទាំងគ្រប់គ្រងស្មៀន ដើម្បីទទួលយកប្រភេទការចូលផ្សេងៗដូចជា Google និងការចូលអ៊ីមែល៖ /sign-in ដើម្បីបង្កើតទំព័រចូល សូមចូលទៅកាន់ផ្ទាំងគ្រប់គ្រងស្មៀន ហើយរៀបចំវិធីសាស្ត្រចូលចាំបាច់សម្រាប់គម្រោង។ ប្រសិនបើអ្នកប្រើត្រូវបានចូល មុខងារទាញយក និង ពីស្មៀន។ តម្លៃទាំងនេះគឺចាំបាច់ដើម្បីធានាថាអ្នកប្រើប្រាស់ត្រូវបានចូល ហើយបន្ទាប់មកអ្នកអាចប្រើ ដើម្បីបំពេញជួរនីមួយៗនៅក្នុងមូលដ្ឋានទិន្នន័យរបស់អ្នក។ userId authToken userId ដើម្បីធ្វើការផ្លាស់ប្តូរទៅលើមូលដ្ឋានទិន្នន័យដែលមានសុវត្ថិភាព RLS អ្នកត្រូវទាញ ពីអថេរបរិស្ថាន។ DATABASE_AUTHENTCATED_URL តក្កវិជ្ជាស្នូលសម្រាប់ការអនុវត្តសុវត្ថិភាព RLS ស្ថិតនៅក្នុង ។ ឧទាហរណ៍ SQL Neon ត្រូវបានចាប់ផ្តើមដោយប្រើអថេរបរិស្ថាន និងសញ្ញាសម្គាល់អត្តសញ្ញាណ។ មុខងារ ធ្វើការហៅ SQL ហើយបញ្ចូល user_id (និងពេលវេលាបច្ចុប្បន្ន) ទៅក្នុងមូលដ្ឋានទិន្នន័យ PostgreSQL បន្ទាប់មកមុខងារ សួរ DB សម្រាប់ការចូលថ្មីៗបំផុតចំនួន 10 ។ LoaderFunction loginResponse last10LoginsResponse ទីបំផុត 10LoginsResponse ត្រូវបានត្រឡប់ពីមុខងារកម្មវិធីផ្ទុក។ last10LoginsResponse មុខងារ នៅក្នុងឯកសារ បង្ហាញប្លង់នៃទំព័រដូចដែលបានបង្ហាញក្នុងអត្ថបទខាងក្រោម៖ Index() _index.tsx export default function Index() { const logins = useLoaderData(); return ( <div> <h1>Signed in</h1> <p>You are signed in!</p> <p> <UserButton /></p> <div> <h1>Recent Logins</h1> {logins?.map((logins) => ( <li key={logins.id}> {logins.user_id} login at: {logins.login_at} </li> ))} </div> <p>< SignOutButton > Sign Out</ SignOutButton ></p> </div> ); } កូដខាងលើទាញយកការឆ្លើយតបពី ដែលមានធាតុចូល 10 ចុងក្រោយ។ ការឆ្លើយតបនេះបង្កើតទំព័រដែលប្រាប់អ្នកប្រើថាពួកគេបានចូល រាយបញ្ជីការចូលចុងក្រោយរបស់ពួកគេចំនួន 10 និងបង្ហាញប៊ូតុងចេញដូចបង្ហាញខាងក្រោម៖ LoaderFunction ក្នុងឧទាហរណ៍នេះ ក៏ត្រូវបានបង្ហាញផងដែរដើម្បីបញ្ជាក់យ៉ាងច្បាស់ថាមានតែទិន្នន័យចូលសម្រាប់អ្នកប្រើប្រាស់ដែលបានចូលប៉ុណ្ណោះដែលអាចមើលឃើញ។ user_id ដោយប្រើវិនដូអនាមិក អ្នកអាចចូលដោយប្រើគណនី Google ទីពីរ ហើយមើលទិន្នន័យចំហៀងសម្រាប់អ្នកប្រើប្រាស់ផ្សេងៗគ្នា៖ ចំណាំថាពេលវេលាចូលត្រួតគ្នា ប៉ុន្តែដោយប្រើ Row-Level Security នៅក្នុងមូលដ្ឋានទិន្នន័យ អ្នកនឹងការពារការលេចធ្លាយទិន្នន័យនៅលើគណនីនានា។ ជួរដេកអាចត្រូវបានស្រង់ចេញ និងបង្ហាញសម្រាប់អ្នកប្រើដែលបានផ្ទៀងផ្ទាត់ប៉ុណ្ណោះ។ សេចក្តីសន្និដ្ឋាន ការរក្សាទិន្នន័យជាឯកជនគឺជាករណីប្រើប្រាស់ដ៏សំខាន់។ ដោយសារកម្មវិធីតែងតែរក្សាទុកព័ត៌មានឯកជន វាត្រូវតែមានសុវត្ថិភាព ដើម្បីរក្សាទិន្នន័យនៅក្នុងដៃស្តាំ។ អ្នកប្រើប្រាស់មានការការពារផ្នែកច្បាប់កាន់តែច្រើនឡើងៗដូចជា GDPR ហើយឧបករណ៍ដូចជា Neon Authorize ធ្វើឱ្យមានភាពងាយស្រួលក្នុងការអនុវត្ត Row Level Security ដើម្បីការពារទិន្នន័យអតិថិជនរបស់អ្នក។ នៅក្នុងការប្រកាសនេះ យើងបានដើរតាមជំហានដែលត្រូវការដើម្បីបើកដំណើរការ Row Level Security នៅក្នុងមូលដ្ឋានទិន្នន័យ Neon។ ការប្រើប្រាស់ RLS ជាមួយនឹងទិន្នន័យរបស់អតិថិជនរបស់យើងធានាថាមានតែអ្នកប្រើប្រាស់ដែលបានចូលប៉ុណ្ណោះដែលមានលិខិតសម្គាល់ដើម្បីទាញយកទិន្នន័យផ្ទាល់ខ្លួនរបស់ពួកគេ។ បន្ថែម ទៅកម្មវិធីរបស់អ្នកថ្ងៃនេះជាមួយ Neon ។ Row Layer Security