By گابریل L. Manor
گابریل L. مانور
Supabase ای میل، OAuth، اور جادو لنکس کے لئے داخلہ کی حمایت کے ساتھ آپ کے ایپ میں تصدیق کو شامل کرنے کے لئے آسان بناتا ہے. لیکن اگرچہ Supabase Auth آپ کے صارفین کے بارے میں کام کرتا ہے، تو آپ کو اکثر ایک تصدیق کی سطح کی ضرورت ہوتی ہے.
Supabase میں داخلہ auth اور Row Level Security (RLS) کے ساتھ ایک عظیم بیک اینڈ پیش کرتا ہے، fine-grained اجازتیں - خاص طور پر صارفین اور اعداد و شمار کے درمیان تعلقات پر مبنی - آسان سے دور ہے.
فائدہ مند خصوصیاتصارفین اور ڈیٹا کے درمیان تعلقات
آپ کو ڈیٹا کو ترمیم یا حذف کرنے جیسے کارروائیوں کو وسائل کے مالکان کو محدود کرنا چاہئے، صارفین کو ان کے اپنے مواد پر ووٹ کرنے سے روکنے، یا مختلف صارف کرداروں کے لئے مختلف اجازتوں کو نافذ کرنے سے روکنا چاہئے.
یہ ٹیوٹوریل ایک Next.js ایپلی کیشن میں Supabase تصدیق اور لائسنس کو کیسے لاگو کرنے کے بارے میں جانتا ہے.
Supabase تصدیق اور لائسنسNext.js کے بارے میںWe'll start with Supabase Auth for login and session management, then add authorization rules using Relationship-Based Access Control (ReBAC), enforced through Supabase Edge Functions and a local Policy Decision Point (PDP).
سائپ بیس آؤٹمقاصد کی اجازتRelationship-Based Access Control (ReBAC)Supabase Edge Functionslocal Policy Decision Point (PDP)
آخرت میں، آپ کو ایک حقیقی وقت میں مشترکہ سروے کے ایپلی کیشن مل جائے گا جو دونوں عوامی اور محفوظ کارروائیوں کو حمایت کرتا ہے - اور ایک انعطاف پذیر اجازت کے نظام آپ کے ایپلی کیشن کی ترقی کے ساتھ ترقی کرسکتے ہیں.
آپ کیا کر رہے ہیں
اس گائیڈ میں، ہم Supabase اور Next.js کا استعمال کرتے ہوئے ایک حقیقی وقت میں ووٹنگ اپلی کیشن بنائیں گے جو کارروائی میں تصدیق اور مجازیت دونوں کو دکھاتا ہے.
سائپ بیسNext.js کے بارے میں
آپ کا استعمال کرتے ہوئے صارفین کو سروے بنانے، دوسروں پر ووٹ دینے اور صرف ان کے اپنے مواد کا انتظام کرنے کی اجازت دیتا ہے. یہ دکھاتا ہے کہ کس طرح Supabase Auth لاگ ان / سائن اپ کے لئے لاگو کیا جا سکتا ہے اور کس طرح آپ کی اجازت کی پالیسی کو لاگو کیا جا سکتا ہے جو کس کو ووٹ، ترمیم، یا حذف کر سکتا ہے.
سائپ بیس آؤٹآپ کی اجازت کی پالیسی
We will use Supabase’s core features—Auth، Postgres، RLS، Realtime، اور Edge Functions—combined with a Relationship-Based Access Control (ReBAC) model to enforce per-user and per-resource access rules.
آپبھارتیںrls کے بارے میںRealtime کے بارے میںایڈج فیکٹریز رشتے پر مبنی رسائی کنٹرول (ReBAC)تکنیکی Stack
- Supabase – Backend-as-a-service for database, authentication, realtime, and edge functions
- Next.js – Frontend framework for building the app UI and API routes
- Permit.io – (for ReBAC) to define and evaluate authorization logic via PDP
- Supabase CLI – To manage and deploy Edge Functions locally and in production
مقاصد
- Node.js installed
- Supabase account
- Permit.io account
- Familiarity with React/Next.js
- Starter project repo
اس اپلی کیشن کیا کر سکتا ہے؟
ڈیمو ایپلی کیشن ایک حقیقی وقت میں ووٹنگ پلیٹ فارم ہے جو Next.js اور Supabase کے ساتھ تعمیر کیا گیا ہے، جہاں صارفین ووٹ بن سکتے ہیں اور دوسروں پر ووٹ کرسکتے ہیں.
- کسی بھی صارف (مصمم یا نہیں) عوامی سروے کی فہرست دیکھ سکتا ہے
- ایک صارف صرف تصدیق شدہ صارفین کو سروے بنا سکتے ہیں اور ووٹ کر سکتے ہیں
- ایک صارف اپنے پیدا کردہ سروے پر ووٹ نہیں کر سکتا
- ایک صارف ایک سروے کا تخلیق کرنے والا صرف اسے ترمیم یا حذف کر سکتا ہے
تصویریں
ہم ان عام اقدامات پر عمل کریں گے:
- Project، Schema، auth، and RLS
- Build core app features like poll creation and voting
- Model authorization rulesPermit.io
- Create Supabase Edge Functions for syncing users, allocating roles, and checking permissions
- Enforce policies in the app frontend using those edge functions
آپ شروع کریں -
Project میں Supabase کی تشکیل
Project میں Supabase کی تشکیلمختصر: شروع کرنے والے ٹیبلٹ کو کلون کریں
I've already created a starter template on GitHub with all the code you need to start so we can focus on implementing Supabase and Permit.io.
starter templateGitHub کے لئے
آپ مندرجہ ذیل کمانڈ کو چلانے کے ذریعے منصوبہ کو کلن کرسکتے ہیں:
github <https://github.com/permitio/supabase-fine-grained-authorization>
git clone <https://github.com/permitio/supabase-fine-grained-authorization>
ایک بار جب آپ نے منصوبے کو کلون کیا ہے تو، منصوبے کے ڈائریکٹری پر براہ مہربانی براہ مہربانی براہ مہربانی انسٹال کریں:
cd realtime-polling-app-nextjs-supabase-permitio npm install
cd realtime-polling-app-nextjs-supabase-permitio
npm install
Supabase میں ایک نیا پروجیکٹ بنانے
شروع کرنے کے لئے:
-
Go to https://supabase.com and sign in or create an account.
-
Click "New Project" and fill in your project name, password, and region.
-
Once created, go to Project Settings → API and note your Project URL and Anon Key — you’ll need them later.
Go to https://supabase.com and sign in or create an account.
Go to https://supabase.com and sign in or create an account.
https://supabase.comClick "نئی پروجیکٹ" اور اپنے پروجیکٹ کا نام، پاس ورڈ، اور علاقے درج کریں.
Click "نئی پروجیکٹ" اور اپنے پروجیکٹ کا نام، پاس ورڈ، اور علاقے درج کریں.
"نئی منصوبہ"ایک بار پیدا ہونے کے بعد، Project Settings → API پر جائیں اور اپنے Project URL اور Anon Key کو نوٹ کریں - آپ کو بعد میں ان کی ضرورت ہوگی.
ایک بار پیدا ہونے کے بعد، Project Settings → API پر جائیں اور اپنے Project URL اور Anon Key کو نوٹ کریں - آپ کو بعد میں ان کی ضرورت ہوگی.
پروجیکٹ ترتیبات → APIProject URL کے بارے میں معلوماتAnon Key کے بارے میں
Supabase میں تصدیق اور ڈیٹا بیس کی تشکیل
We will use Supabase’s built-in email/password auth:
-
ایک طرف کی بار میں آیٹسٹنگ → سپلائرز
-
Email سپلائر کو فعال کریں
-
(مختصر) ٹیسٹ کے لئے ای میل کی تصدیق کو غیر فعال کریں، لیکن پیداوار کے لئے اس کو فعال رکھیں
بچے کی بار میں آٹوٹیشن → سپلائرز
بچے کی بار میں آٹوٹیشن → سپلائرز
پر جائیںتصویری → سپلائرزآپ کو Email فراہم کرنے کی اجازت دیں
آپ کو Email فراہم کرنے کی اجازت دیں
ای میل(مختصر) ٹیسٹ کے لئے ای میل کی تصدیق کو غیر فعال کریں، لیکن پیداوار کے لئے اسے فعال رکھیں
(مختصر) ٹیسٹ کے لئے ای میل کی تصدیق کو غیر فعال کریں، لیکن پیداوار کے لئے اسے فعال رکھیں
DataBase Schema کی تخلیق
یہ اپلی کیشن تین اہم ٹیبلز کا استعمال کرتا ہے: polls
، options
، اور votes
.polls
options
votes
SQL ایڈیٹر
-- ایک سروے ٹیبل بنائیں CREATE TABLE polls ( id UUID DEFAULT uuid_generate_v4() PRIMARY KEY, question TEXT NOT NULL, created_by UUID REFERENCES auth.users(id) NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()), creator_name TEXT NOT NULL, expires_at TIMESTAMP WITH TIME ZONE NOT NULL, ); -- ایک اختیارات ٹیبل بنائیں CREATE TABLE options ( UUID IDFAULT uuid_generate_v4() PRIMARY KEY, pollid UUID REFERENCES polls(id) ON DELETE CASCADE-- Create a polls table
CREATE TABLE polls (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
question TEXT NOT NULL,
created_by UUID REFERENCES auth.users(id) NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()),
creator_name TEXT NOT NULL,
expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
);
-- Create an options table
CREATE TABLE options (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
poll_id UUID REFERENCES polls(id) ON DELETE CASCADE,
text TEXT NOT NULL,
);
-- Create a votes table
CREATE TABLE votes (
id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
poll_id UUID REFERENCES polls(id) ON DELETE CASCADE,
option_id UUID REFERENCES options(id) ON DELETE CASCADE,
user_id UUID REFERENCES auth.users(id),
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc', NOW()),
UNIQUE(poll_id, user_id)
);
Row Level Security (RLS) کی اجازت دیتا ہے
Enable RLS for each table and define policies:
RLS-- Polls policies ALTER TABLE polls ENABLE ROW LEVEL SECURITY; CREATE POLICY "Anyone can view polls" ON polls FOR SELECT USING (true); CREATE POLICY "Anyone can view options" ON options FOR SELECT USING (true); CREATE POLICY "Poll creators can add options" ON OPTIONS FOR INSERT TO AUTHENTIZED WITH CHECK (auth.uid() = created_by); -- OPTIONS POLICY ALTER TABLE options ENABLE ROW LEVEL SECURITY (EXISTS (SELECT 1 FROM polls WHERE votes idERE = options.pollid_IDECECT AND created auth_by auth-- Polls policies
ALTER TABLE polls ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Anyone can view polls" ON polls
FOR SELECT USING (true);
CREATE POLICY "Authenticated users can create polls" ON polls
FOR INSERT TO authenticated
WITH CHECK (auth.uid() = created_by);
-- Options policies
ALTER TABLE options ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Anyone can view options" ON options
FOR SELECT USING (true);
CREATE POLICY "Poll creators can add options" ON options
FOR INSERT TO authenticated
WITH CHECK (
EXISTS (
SELECT 1 FROM polls
WHERE id = options.poll_id
AND created_by = auth.uid()
)
);
-- Votes policies
ALTER TABLE votes ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Anyone can view votes" ON votes
FOR SELECT USING (true);
CREATE POLICY "Authenticated users can vote once" ON votes
FOR INSERT TO authenticated
WITH CHECK (
auth.uid() = user_id AND
NOT EXISTS (
SELECT 1 FROM polls
WHERE id = votes.poll_id
AND created_by = auth.uid()
)
);
Supabase کے حقیقی وقت کی خصوصیات کا استعمال کرنے کے لئے:
-
In the sidebar, go to Table Editor
-
For each of the three tables (polls
, options
, votes
):
-
Click the three dots → Edit Table
-
Toggle "Enable Realtime"
-
Save changes
In the sidebar, go to Table Editor
بچے کی بار میں Table Editor
پر جائیںٹابلیس ایڈیٹر
For each of the three tables (polls
, options
, votes
):
-
Click the three dots → Edit Table
-
Toggle "Enable Realtime"
-
Save changes
تین ٹیبلوں میں سے ہر ایک کے لئے (polls
، options
، votes
):
polls
options
votes
-
Click the three dots → Edit Table
-
Toggle "Enable Realtime"
-
Save changes
تین پوائنٹس پر کلک کریں → Edit Table
بچوں پر کلک کریں Edit Table
دوسرے ٹیبل Toggle "Realtime"
Toggle "Realtime کو فعال کریں"
"Realtime کی اجازت دیتا ہے"
Save changes
تبدیلیوں کو محفوظ کریں
App میں Supabase Email Authentication کو نافذ کرنا
اس ڈیمو ایپ میں، کوئی بھی اپلی کیشن پر دستیاب سروے کی فہرست کو دیکھ سکتا ہے، فعال اور ختم ہونے والے دونوں. ایک سروے کی تفصیلات کو دیکھنے کے لئے، کسی بھی سروے پر انتظام، یا ووٹ کرنے کے لئے، صارف کو لاگ ان ہونا ضروری ہے. ہم اس منصوبے کے لئے تصدیق کے ذریعہ ای میل اور پاس ورڈ کا استعمال کریں گے. آپ کے Next.js پروجیکٹ میں .env.local
:
.env.local
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
آپ کے لاگ ان اجزاء کو ای میل / پاس ورڈ کے ذریعے سائن اپ اور لاگ ان دونوں کو منظم کرنے کے لئے اپ ڈیٹ کریں:
import { useState } from "react"; import { createClient } from "@/utils/supabase/component"; const LogInButton = () => { const supabase = createClient(); async function logIn() { const { error } = await supabase.auth.signUp email({ data: user_name: userName, }, }); if (error) { setError(error.message); } else { setShowModal(false); } } else async function signUp() { const error } { const error } = await supabase.auth.signUp{ email, password options: { data: user_name, } }; if (error) {Error(error.messageimport { useState } from "react";
import { createClient } from "@/utils/supabase/component";
const LogInButton = () => {
const supabase = createClient();
async function logIn() {
const { error } = await supabase.auth.signInWithPassword({
email,
password,
});
if (error) {
setError(error.message);
} else {
setShowModal(false);
}
}
async function signUp() {
const { error } = await supabase.auth.signUp({
email,
password,
options: {
data: {
user_name: userName,
},
},
});
if (error) {
setError(error.message);
} else {
setShowModal(false);
}
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
if (isLogin) {
await logIn();
} else {
await signUp();
}
};
return (
<>
<button
onClick={() => setShowModal(true)}
className="flex items-center gap-2 p-2 bg-gray-800 text-white rounded-md">
Log In
</button>
...
</>
);
};
export default LogInButton;
یہاں، ہم ایک صارف کو لاگ ان کرنے کے لئے Supabase کی signInWithPassword
طریقہ کار کا استعمال کرتے ہیں اور signUp
طریقہ کار کو اپنے ای میل اور پاس ورڈ کے ساتھ ایک نیا صارف کو لاگ ان کرنے کے لئے استعمال کرتے ہیں.
ہم صارف کے میٹا ڈیٹا میں user_name
میدان میں صارف کا نام بھی ذخیرہ کرتے ہیں.signInWithPassword
signUp
user_name
آپ بھی supabase.auth.signOut()
استعمال کرسکتے ہیں کہ صارفین کو لاگ ان کریں اور ان کو ہدایت کریں:
supabase.auth.signOut()
Import { createClient } from "@/utils/supabase/component"; import { useRouter } from "next/router"; const LogOutButton = ({ closeDropdown }: { closeDropdown: () => void }) => { const router = useRouter(); const supabase = createClient(); const handleLogOut = async () => { await supabase.auth.signOut(); closeDropdown(); router.push("/"}); return ( ... ); } export default LogOutButton;
import { createClient } from "@/utils/supabase/component";
import { useRouter } from "next/router";
const LogOutButton = ({ closeDropdown }: { closeDropdown: () => void }) => {
const router = useRouter();
const supabase = createClient();
const handleLogOut = async () => {
await supabase.auth.signOut();
closeDropdown();
router.push("/");
};
return (
...
);
};
export default LogOutButton;
یہاں، ہم Supabase سے signOut
طریقہ کار کا استعمال کرتے ہیں، صارف کو لاگ ان کرنے اور ان کو ہوم پیج پر ہدایت کرنے کے لئے.
signOut
صارف کی تصدیق کی حالت میں تبدیلیوں کے لئے سننے
صارف کی تصدیق کی حالت میں تبدیلیوں کے لئے سننا ہمیں صارف کی تصدیق کی حالت پر مبنی UI کو اپ ڈیٹ کرنے کی اجازت دیتا ہے.
- Login/Logout بٹنز جیسے UI عناصر کو دکھائیں / چھپائیں
- محتمل طور پر محفوظ صفحات (جیسے ووٹنگ یا سروے کا انتظام) تک رسائی کو محدود کریں
- محتمل صارفین کو صرف محدود کارروائیوں کو انجام دینے کے قابل بنائیں
Show/hide UI elements such as login/logout buttons محتمل طور پر محفوظ صفحات تک رسائی کو محدود کریں (مثال کے طور پر ووٹنگ یا سروے کا انتظام کریں) مزید تصدیق شدہ صارفین کو محدود کارروائیوں کو انجام دے سکتے ہیں
We will use supabase.auth.onAuthStateChange()
to listen to these events and update the app accordingly.
supabase.auth.onAuthStateChange()
In the Layout.tsx
file: Track Global Auth State
In میںLayout.tsx
file: ٹریک عالمی Auth State
import React، { useEffect, useState } سے "react"; import { createClient } سے "@/utils/supabase/component"; import { User } سے "@supabase/supabase-js"; const Layout = ({ بچوں }: { بچوں: React.ReactNode }) => { data = supabase.authon.AuthonStateChange((event, session) => useEffect(() => { const fetchUser = async () => { const supabase = createClient(); { data = supabase.authon.AuthonStateChange((event, session) => { set(Useression?.import React, { useEffect, useState } from "react";
import { createClient } from "@/utils/supabase/component";
import { User } from "@supabase/supabase-js";
const Layout = ({ children }: { children: React.ReactNode }) => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
const fetchUser = async () => {
const supabase = createClient();
const { data } = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user || null);
});
return () => {
data.subscription.unsubscribe();
};
};
fetchUser();
}, []);
return (
...
);
};
export default Layout;
مرنے والے صفحات پر رسائی محدود
جیسے صفحات پر سروے کی تفصیلات یا سروے کے انتظام، آپ کو غیر معتبر صارفین کو ان تک رسائی حاصل کرنے سے روکنے کے لئے تصدیق کی حالت میں تبدیلیوں کے لئے بھی سننا چاہئے.
پول کی تفصیلاتپرس مینجمنٹ
اس طرح یہ pages/polls/[id].tsx
میں نظر آتا ہے:
pages/polls/[id].tsx
Import { createClient } from "@/utils/supabase/component"; import { User } from "@supabase/supabase-js"; const Page = () => { const [user, setUser] = useState<User Átha null> (null); useEffect(() => { const fetchUser = async () => { const supabase = createClient(); const { data } = supabase.auth.onAuthStateChange((انٹ، سیشن) => { setUser(session?.user at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at atimport { createClient } from "@/utils/supabase/component";
import { User } from "@supabase/supabase-js";
const Page = () => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
const fetchUser = async () => {
const supabase = createClient();
const { data } = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user || null);
setLoading(false);
});
return () => {
data.subscription.unsubscribe();
};
};
fetchUser();
}, []);
return (
...
);
export default Page;
اور ایک اسی طرح کا نمونہ pages/polls/manage.tsx
میں لاگو ہوتا ہے، جہاں صارفین کو صرف ان کے اپنے سروے دیکھنا چاہئے جب وہ لاگ ان کر رہے ہیں:
pages/polls/manage.tsx
import { createClient } سے "@/utils/supabase/component"; import { User } سے "@supabase/supabase-js"; const Page = () => { const [user, setUser] = useState<User Átha null> const supabase = createClient(); useEffect(() => { const fetchUser = async () => { const { data } = supabase.auth.onAuthStateChangeevent((session, session) => { setUser(session?.user at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at at atimport { createClient } from "@/utils/supabase/component";
import { User } from "@supabase/supabase-js";
const Page = () => {
const [user, setUser] = useState<User | null>(null);
const supabase = createClient();
useEffect(() => {
const fetchUser = async () => {
const { data } = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user || null);
if (!session?.user) {
setLoading(false);
}
});
return () => {
data.subscription.unsubscribe();
};
};
fetchUser();
}, []);
return (
...
);
};
export default Page;
یہ نمونے اس بات کو یقینی بناتے ہیں کہ آپ کا UI صارف کی موجودہ تصدیق کی حالت کا تعین کرتا ہے اور ہم بعد میں شامل کرنے والے تصدیق کی چیک کے لئے بنیاد بناتا ہے. مثال کے طور پر، آپ بعد میں اس user
اشیاء کا استعمال کریں گے جب checkPermission
Edge Function کو کال کرتے ہیں کہ کیا ایک صارف کو ووٹ کرنے کی اجازت ہے یا ایک مخصوص سروے کا انتظام کرنے کی اجازت ہے.
user
checkPermission
پرسنگ اپلی کیشن کی سرگرمیوں کی تعمیر
Supabase کی ترتیب اور تصدیق کے ساتھ کام کرتے ہوئے، ہم اب سروے ایپ کی بنیادی سرگرمیوں کو تعمیر کرسکتے ہیں.
- آپ نئے سروے پیدا کریں
- آپ کے سروے کو حقیقی وقت میں شامل کریں اور دکھائیں
- ایک ووٹنگ سسٹم کو لاگو کریں
آپ کے بارے میں مزید جانیں Fetching and displaying polls in real-time ایک ووٹنگ نظام کا استعمال کریں
یہ ہمیں بنیادی اپلی کیشن کے رویے فراہم کرتا ہے جو ہم جلد ہی فوائد کے ساتھ محفوظ کریں گے.
آپ کے لئے نئے سروے پیدا کریں
صارفین کو سروے بنانے کے لئے لاگ ان ہونا ضروری ہے. ہر سروے میں ایک سوال، ایک اختتام کی تاریخ، اور ایک سیٹ اختیارات شامل ہیں. ہم یہ بھی ریکارڈ کرتے ہیں کہ سروے کو کس نے پیدا کیا تاکہ ہم بعد میں اس رشتے کو رسائی کنٹرول کے لئے استعمال کرسکتے ہیں.
NewPoll.tsx
کے اندر، تصدیق شدہ صارف کو حاصل کریں، اور Supabase استعمال کرتے ہوئے سروے اور اس کے اختیارات کو داخل کریں:
NewPoll.tsx
کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپیimport React, { useEffect, useState } from "react";
import { createClient } from "@/utils/supabase/component";
import { User } from "@supabase/supabase-js";
const NewPoll = () => {
const [user, setUser] = useState<User | null>(null);
const supabase = createClient();
useEffect(() => {
const fetchUser = async () => {
const supabase = createClient();
const { data } = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user || null);
});
return () => {
data.subscription.unsubscribe();
};
};
fetchUser();
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (question.trim() && options.filter(opt => opt.trim()).length < 2) {
setErrorMessage("Please provide a question and at least two options.");
return;
}
// Create the poll
const { data: poll, error: pollError } = await supabase
.from("polls")
.insert({
question,
expires_at: new Date(expiryDate).toISOString(),
created_by: user?.id,
creator_name: user?.user_metadata?.user_name,
})
.select()
.single();
if (pollError) {
console.error("Error creating poll:", pollError);
setErrorMessage(pollError.message);
return;
}
// Create the options
const { error: optionsError } = await supabase.from("options").insert(
options
.filter(opt => opt.trim())
.map(text => ({
poll_id: poll.id,
text,
}))
);
if (!optionsError) {
setSuccessMessage("Poll created successfully!");
handleCancel();
} else {
console.error("Error creating options:", optionsError);
setErrorMessage(optionsError.message);
}
};
return (
...
);
};
export default NewPoll;
ہم بعد میں Permit.io میں "Creator" کردار کو تنصیب کرنے کے لئے یہاں ایک Edge Function کال کریں گے.
پرسوں کو فٹنگ اور دکھانے
Polls کو active (نہیں ختم) اور past (نہیں ختم) میں تقسیم کیا جاتا ہے. آپ کو موجودہ ٹائم سٹیمپ کی طرف سے فلٹر کیا گیا Supabase سوالات کا استعمال کرتے ہوئے ان کو حاصل کرسکتے ہیں، اور فوری طور پر تبدیلیوں کو ظاہر کرنے کے لئے حقیقی وقت کے دستاویزات کو قائم کرسکتے ہیں.
فعالپچھلا
pages/index.tsx
سے مثال:
pages/index.tsx
٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭import { PollProps } from "@/helpers";
import { createClient } from "@/utils/supabase/component";
export default function Home() {
const supabase = createClient();
useEffect(() => {
const fetchPolls = async () => {
setLoading(true);
const now = new Date().toISOString();
try {
// Fetch active polls
const { data: activePolls, error: activeError } = await supabase
.from("polls")
.select(
`
id,
question,
expires_at,
creator_name,
created_by,
votes (count)
`
)
.gte("expires_at", now)
.order("created_at", { ascending: false });
if (activeError) {
console.error("Error fetching active polls:", activeError);
return;
}
// Fetch past polls
const { data: expiredPolls, error: pastError } = await supabase
.from("polls")
.select(
`
id,
question,
expires_at,
creator_name,
created_by,
votes (count)
`
)
.lt("expires_at", now)
.order("created_at", { ascending: false });
if (pastError) {
console.error("Error fetching past polls:", pastError);
return;
}
setCurrentPolls(activePolls);
setPastPolls(expiredPolls);
} catch (error) {
console.error("Unexpected error fetching polls:", error);
} finally {
setLoading(false);
}
};
fetchPolls();
// Set up real-time subscription on the polls table:
const channel = supabase
.channel("polls")
.on(
"postgres_changes",
{
event: "*",
schema: "public",
table: "polls",
},
fetchPolls
)
.subscribe();
return () => {
supabase.removeChannel(channel);
};
}, []);
return (
...
);
}
صارف سروے کو دیکھنے اور منظم کرنے
یہاں، ہم Supabase میں polls
ٹیبل سے فعال اور ماضی کے سروے حاصل کر رہے ہیں. ہم بھی polls
ٹیبل میں تبدیلیوں کے لئے سننے کے لئے ایک حقیقی وقت کے اختتام کو قائم کر رہے ہیں تاکہ ہم تازہ ترین سروے کے اعداد و شمار کے ساتھ UI کو اپ ڈیٹ کرسکتے ہیں۔ فعال اور ماضی کے سروے کے درمیان فرق کرنے کے لئے، ہم ہر سروے کے ختم ہونے کی تاریخ کو موجودہ تاریخ کے ساتھ موازنہ کر رہے ہیں.
polls
polls
pages/manage.tsx
صفحے کو اپ ڈیٹ کریں اور صرف صارف کی طرف سے پیدا کردہ سروے کو تلاش کریں:
pages/manage.tsx
import { PollProps } سے "@/helpers"; const Page = () => { useEffect(() => { if (!user?.id) return; const fetchPolls = async () => { try { const_at", { ascending: error } = await supabase .from("polls") .select( `id, question, expires_at, creator_name, created_by, votes (count) `) .eq("created_by", user.id) .order("created_at", { ascending: error }); if (error) default consoleerror("Error fet polls:", error); return; } setPolls filter(data return schol.de [=import { PollProps } from "@/helpers";
const Page = () => {
useEffect(() => {
if (!user?.id) return;
const fetchPolls = async () => {
try {
const { data, error } = await supabase
.from("polls")
.select(
`
id,
question,
expires_at,
creator_name,
created_by,
votes (count)
`
)
.eq("created_by", user.id)
.order("created_at", { ascending: false });
if (error) {
console.error("Error fetching polls:", error);
return;
}
setPolls(data || []);
} catch (error) {
console.error("Unexpected error fetching polls:", error);
} finally {
setLoading(false);
}
};
fetchPolls();
// Set up real-time subscription
const channel = supabase
.channel(`polls_${user.id}`)
.on(
"postgres_changes",
{
event: "*",
schema: "public",
table: "polls",
filter: `created_by=eq.${user.id}`,
},
fetchPolls
)
.subscribe();
return () => {
supabase.removeChannel(channel);
};
}, [user]);
return (
...
);
};
export default Page;
یہاں، ہم صرف صارف کی طرف سے تخلیق کردہ سروے حاصل کرتے ہیں اور polls
ٹیبل میں حقیقی وقت کے اپ ڈیٹس کو سنتے ہیں تاکہ UI تازہ ترین سروے کے اعداد و شمار کے ساتھ اپ ڈیٹ کیا جاتا ہے.
polls
اس کے علاوہ، PollCard
اجزاء کو اپ ڈیٹ کریں تاکہ اگر ایک لاگ ان شدہ صارف سروے کی تخلیق کرنے والا ہے تو، سروے کو ترمیم کرنے اور حذف کرنے کے لئے آئکنوں کو سروے میں دکھایا جائے گا.
PollCard
import { createClient} سے "@/utils/supabase/component"; import { User } سے "@supabase/supabase-js"; const PollCard = ({ poll }: { poll: PollProps }) => { const data } = supabase.auth.onAuthStateChangeevent(( session, session) => { setUser(session.user. قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدم قدمimport { createClient } from "@/utils/supabase/component";
import { User } from "@supabase/supabase-js";
const PollCard = ({ poll }: { poll: PollProps }) => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
const supabase = createClient();
const fetchUser = async () => {
const { data } = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user || null);
setLoading(false);
});
return () => {
data.subscription.unsubscribe();
};
};
fetchUser();
}, []);
return (
...
)}
</Link>
);
};
export default PollCard;
تو اب، ایک سروے کارڈ پر، اگر لاگ ان کردہ صارف سروے کی تخلیق کرنے والا ہے تو، سروے کو ترمیم اور حذف کرنے کے لئے آئکنز ان کو دکھایا جائے گا.
پرسٹ ووٹنگ کے نظام کو لاگو کرنے
پرسٹنگ کی منطق کے مطابق:
- ایک صارف پر صرف ایک ووٹ
- Creators cannot vote on their own polls
- Votes are stored in the
votes
table - Results are displayed and updated in real time
ایک صارف پر صرف ایک ووٹ Creators cannot vote on their own polls مقالات کو votes
ٹیبل میں ذخیرہ کیا جاتا ہے votes
تعدادات واقعی وقت میں دکھایا جاتا ہے اور اپ ڈیٹ کیا جاتا ہے
ہمارا خیال ہے کہ ViewPoll.tsx
اجزاء میں یہ کیسے کام کرتا ہے:
ViewPoll.tsx
Logged-In User کو فٹ کریںWe need the current user’s ID to determine voting eligibility and record their vote.
Fetch the Logged-In User پر کلک کریں
Import { createClient } from "@/utils/supabase/component"; import { User } from "@supabase/supabase-js"; const ViewPoll = () => { const [user, setUser] = useState<User Átha null>(null); const supabase = createClient(); useEffect(() const fetchUser = async () => { const data: { user }, } = await supabase.auth.getUser(); setUser(user); }; fetchUser(); }, []; </>Pre>import { createClient } from "@/utils/supabase/component";
import { User } from "@supabase/supabase-js";
const ViewPoll = () => {
const [user, setUser] = useState<User | null>(null);
const supabase = createClient();
useEffect(()
const fetchUser = async () => {
const {
data: { user },
} = await supabase.auth.getUser();
setUser(user);
};
fetchUser();
}, []);
Load Poll Details and Check Voting Statusایک بار جب ہم صارف کو حاصل کرتے ہیں، ہم حاصل کرتے ہیں:
Load Poll Details and Check Voting Status - پرسٹ خود (مقابلہ اختیارات اور ووٹ کا حساب بھی شامل ہے)
- اگر اس صارف نے پہلے ہی ووٹ دیا ہے
پرسٹ خود (ایکشنز اور ووٹ کی تعداد سمیت) یا اس صارف نے پہلے ہی ووٹ دیا ہے؟
We also call these again later in real-time updates.
useEffect(() => { اگر (!user) { return; } const checkUserVote = async () => { const { data: votes } = await supabase .from("votes") .select("id") .eq("poll_id", query.id) .eq("user_id", user.id) .single(); setHasVoted(!!votes); setVoteLoading(false); }; constchPoll = async () => { const} data = await supabase .from("polls", query.id) .eq(options, *, id, text, votes (count) ) ` ) .eq("quid", query. useEffect(() => {
if (!user) {
return;
}
const checkUserVote = async () => {
const { data: votes } = await supabase
.from("votes")
.select("id")
.eq("poll_id", query.id)
.eq("user_id", user.id)
.single();
setHasVoted(!!votes);
setVoteLoading(false);
};
const fetchPoll = async () => {
const { data } = await supabase
.from("polls")
.select(
`
*,
options (
id,
text,
votes (count)
)
`
)
.eq("id", query.id)
.single();
setPoll(data);
setPollLoading(false);
checkUserVote();
};
fetchPoll();
Real-time اپ ڈیٹس کے لئے سنیں
Real-time اپ ڈیٹس کے لئے سنیںWe subscribe to changes in the votes
table, scope to this poll.When a new vote is cast, we retrieve updated poll data and voting status.
votes
const channel = supabase .channel(`poll-${query.id}`) .on( "postgres_changes", { event: "*", schema: "public", table: "votes", filter: `poll_id=eq.${query.id}`, }, () => { fetchPoll(); checkUserVote(); } ) .subscribe(); return () => { supabase.removeChannel(channel); }; }, [query.id, user]);
const channel = supabase
.channel(`poll-${query.id}`)
.on(
"postgres_changes",
{
event: "*",
schema: "public",
table: "votes",
filter: `poll_id=eq.${query.id}`,
},
() => {
fetchPoll();
checkUserVote();
}
)
.subscribe();
return () => {
supabase.removeChannel(channel);
};
}, [query.id, user]);
آپ کی رائے کا اظہار کریں
آپ کی رائے کا اظہار کریںاگر صارف نے ووٹ نہیں کیا ہے اور ووٹ کرنے کی اجازت ہے (ہم بعد میں اجازت چیک شامل کریں گے)، ہم ان کی ووٹ شامل کریں گے.
const handleVote = async (optionId: string) => { اگر (!user) واپسی؛ چلو { const { error } = await supabase.from("votes").insert({ poll_id: query.id, option_id: optionId, user_id: user.id, }); اگر (!error) { setHasVoted(true); } } catch (error) { console.error("Error voting:", error); }؛
const handleVote = async (optionId: string) => {
if (!user) return;
try {
const { error } = await supabase.from("votes").insert({
poll_id: query.id,
option_id: optionId,
user_id: user.id,
});
if (!error) {
setHasVoted(true);
}
} catch (error) {
console.error("Error voting:", error);
}
};
پرس کے نتائج کو دکھائیںہم نے تمام ووٹوں کی کل تعداد اور ختم ہونے کا وقت پر ایک بونس کا حساب کیا.
آپ اس کے بعد ترقی کے بارز یا اعداد و شمار کو دکھانے کے لئے اس کا استعمال کرسکتے ہیں.
Poll Results دکھائیں
اگر (!pollintza-poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll.poll. if (!poll || pollLoading || voteLoading) return <div>Loading...</div>;
// 6. calculate total votes
const totalVotes = calculateTotalVotes(poll.options);
const countdown = getCountdown(poll.expires_at);
return (
...
);
};
export default ViewPoll;
اس ترتیبات کے ساتھ، آپ کا ووٹنگ سسٹم مکمل طور پر کام کرتا ہے. لیکن اب، جو بھی لاگ ان کرسکتے ہیں، تکنیکی طور پر ووٹ کرنے کی کوشش کرسکتے ہیں - یہاں تک کہ ان کے اپنے سروے پر.کی اجازت کی جانچ پڑتالآپ کی اجازتSupabase Edge Functions
ہم ایسا کرنے سے پہلے، ہم سب سے پہلے اس قسم کی اجازت کی سطح پر نظر ڈالیں جو ہم انسٹال کرنے جا رہے ہیں.
Relationship-Based Access Control (RBAC) کو سمجھنا
Supabase تصدیق اور بنیادی رینج کی سطح کی اجازتیں اچھی طرح سے کام کرتا ہے، لیکن اس طرح کے پیچیدہ قوانین کی حمایت نہیں کرتا:
- آپ کے صارفین کو ان کے اپنے سروے پر ووٹ دینے سے روکنے
- ایک وسائل کے مطابق کرداروں (مثال کے طور پر ایک مخصوص سروے کے لئے "Creator")
- آپ کی بیرونی پالیسیوں کے ذریعے رسائی کا انتظام
صارفین کو اپنے سروے پر ووٹ دینے سے روکنے ہر وسائل کے لئے کرداروں کا تعین کریں (مثال کے طور پر "Creator" ایک مخصوص سروے کے لئے) جاندار پالیسیوں کے ذریعے رسائی کا انتظام
اس طرح کے رشتے پر مبنی اجازتوں کی حمایت کرنے کے لئے، ہم Permit.io کے ساتھ ReBAC کو انسٹال کریں گے.
Relationship-Based Access Control (ReBAC) is a model for managing permissions based on the relationships between users and resources. Instead of relying solely on roles or attributes (as in RBAC or ABAC), ReBAC determines access by evaluating how a user is connected to the resource they’re trying to access.
Relationship-Based Access Control (ReBAC)Relationship-Based Access Control (ReBAC)
اس ٹیوٹوریل میں، ہم ایک ووٹنگ ایپلی کیشن پر ReBAC کو لاگو کرتے ہیں:
- A user who created a poll is the only one who can manage (edit/delete) it
- A user cannot vote on their own poll
- Other authenticated users can vote once per poll
A user who created a poll is the only one who can manage (edit/delete) it پیدا کیا گیاA user cannot vote on their own poll cannot نہیں کر سکتےOwn کے بارے میںایک بار ہر سروے پر دوسرے قابل اعتماد صارفین کو ووٹ دیا جا سکتا ہے
Permit.io میں ان تعلقات کی ماڈلنگ کے ذریعہ، ہم فائدہ مند رسائی کے قوانین کو مقرر کرسکتے ہیں جو Supabase کے داخلہ ریل سطح سیکورٹی (RLS) سے زیادہ ہیں.
ہم Supabase Edge Functions اور Permit کی پالیسی کے انجن کا استعمال کرتے ہوئے ان کو چلانے کے وقت لاگو کریں گے.
For more on ReBAC, check out Permit.io’s ReBAC docs.
Permit.io’s ReBAC docsایکشن کنٹرول ڈیزائن
ہمارے Polling اپلی کیشن کے لئے، ہم مقرر کریں گے:
- One resource with resource-specific actions:
- polls:
create
, read
, delete
, update
.
- Two roles for granting permission levels based on a user's relationship with the resources:
- authenticated: Can perform
create
and read
actions in polls. Can not delete
in polls, or update
actions in polls. Can - creator: CancodeCreate
- ایک ذریعہ جس میں وسائل کی مخصوص کارروائی ہوتی ہے:
- polls:
create
، read
، delete
، update
.
- polls:
create
، read
، delete
، update
.
polls: create
، read
، delete
، update
.پولزcreate
read
delete
update
- :
- authenticated:
create
and read
actions in polls. Can not delete
, or update
actions in polls. - creator: Can
create
, read
, delete
, and update
actions in polls. Can perform read
and create
actions in votes. Can not use create
on their own polls.
٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭٭- authenticated:
create
اور read
کارروائیوں کو سروے میں انجام دے سکتا ہے. delete
یا update
کارروائیوں کو سروے میں انجام دے سکتا ہے. تصویری:create
read
delete
update
اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہCreator: کے بارے میںcreate
read
delete
update
read
create
create
Permit.io کو ترتیب دیں
آپ کی اجازت میں اجازت کے ماڈل کی ترتیبات کے ذریعے چلتے ہیں.
- Create a new project in Permit.io
- Name it something like
supabase-polling
- Define the
polls
resource
- Go to the Policy → Resources tab
- Click “Create Resource”
- Name it
polls
, and add the actions: read
, create
, update
, delete
- Enable ReBAC for the resource
-
Under “ReBAC Options,” define the following roles:
authenticated
creator
-
Click Save
- Create a new project in Permit.io
- Name it something like
supabase-polling
Create a new projectCreate a new project in Permit.io - ایک ایسی چیز کا نام کریں جیسے
supabase-polling
- ایک ایسی چیز کا نام کریں جیسے
supabase-polling
supabase-polling
polls
resource - Policy → Resources tab
- Click “Create Resource”
- Name it
polls
، اور اقدامات شامل کریں: read
، create
، update
، delete
تصویر کریںpolls
مقاصد - Policy → Resources tab
- Click “Create Resource”
- Name it
polls
، اور اقدامات شامل کریں: read
، create
، update
، delete
Go to Policy → Resources tab پولیس → وسائلClick “Create Resource” “Create Resource”Name it polls
، اور اقدامات شامل کریں: read
، create
، update
، delete
polls
read
create
update
delete
مقصد کے لئے ReBAC کو فعال کریں -
مقصد کے اختیارات کے تحت، مندرجہ ذیل کردار ادا کریں:
authenticated
creator
Click Save
Resource کے لئے ReBAC کو فعال کریں -
Rebac اختیارات کے تحت، مندرجہ ذیل کردار ادا کریں:
-
creator
Click Save
Rebac اختیارات کے تحت، مندرجہ ذیل کردار ادا کریں:
authenticated
creator
“ReBAC اختیارات” کے تحت، مندرجہ ذیل کردار ادا کریں:
تصویری
authenticated
creator
creator
Click Save
Click Save
پر کلک کریں محفوظ کریں
آپ نے صرف پیدا کردہ وسائل سے رولز کو دیکھنے کے لئے "لڑکیوں" ٹیب پر پلگ ان کریں. یاد رکھیں کہ اجازت اس ہدایات (admin
، editor
، user
) کو پیدا کیا ہے جو اس ہدایات کے لئے غیر ضروری ہیں.
admin
editor
user
-
Define access policies
- Go to the Policy → Policies tab
- Use the visual matrix to define:
-
authenticated
can read
and create
polls
-
creator
can read
, update
, and delete
polls
-
(Optional) You can configure vote permissions as part of this or via a second resource if you model votes separately
-
Add resource instances
-
Go to Directory → Instances
-
Add individual poll IDs as resource instances (you’ll automate this later when new polls are created)
-
Assign roles to users per poll (e.g. user123
is creator
of poll456
)
Define access policies
- Go to the Policy → Policies tab
- Use the visual matrix to define:
-
authenticated
can read
and create
polls
-
creator
can read
, update
, and delete
polls
-
(Optional) You can configure vote permissions as part of this or via a second resource if you model votes separately
آپ کی رسائی کی پالیسی کا تعین کریں
آپ کی رسائی کی پالیسی کا تعین کریں - > Policy → Policies tab
-
authenticated
read
اور create
polls
creator
read
، update
، اور delete
polls
-
(مختصر) آپ کو اس کے حصہ کے طور پر یا ایک دوسرا وسائل کے ذریعے ووٹنگ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ الگ الگ الگ ووٹنگ
Go to Policy → پالیسییں tab پولیس → پالیسییںتصویر کا استعمال کریں: -
authenticated
can read
and create
polls
-
creator
can read
, update
, and delete
polls
-
(مختصر) آپ اس کے حصہ کے طور پر یا ایک دوسرا وسائل کے ذریعہ ووٹنگ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ ووٹنگ کو منفرد طور پر ماڈل کریں
-
authenticated
کر سکتے ہیں read
اور create
polls
-
creator
کر سکتے ہیں read
, update
, اور delete
polls
-
(مختصر) آپ کو اس کے حصہ کے طور پر یا ایک دوسری وسائل کے ذریعے ووٹنگ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ الگ الگ ہی طرح کا ووٹنگ کر رہے ہیں
authenticated
کر سکتے ہیں read
اور create
polls
authenticated
کر سکتے ہیں read
اور create
polls
authenticated
read
create
creator
read
، update
، اور delete
polls
creator
کر سکتے ہیں read
، update
، اور delete
polls
creator
read
update
delete
(مختصر) آپ اس کے حصے کے طور پر یا دوسری وسائل کے ذریعے ووٹ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ ووٹ کو منفرد طور پر ماڈل کریں
(مختصر) آپ اس کے حصہ کے طور پر یا دوسری وسائل کے ذریعے ووٹ کی اجازتیں ترتیب دے سکتے ہیں اگر آپ ووٹ کو منفرد طور پر ماڈل کرتے ہیں
-
Directory → Instances
-
مختلف سروے ایڈز کو سروے ایڈز کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کرسکتے ہیں)
-
ایک سروے پر صارفین کو کردار ادا کریں (مثلا user123
creator
کے poll456
)
مقالات شامل کریں
مقالات شامل کریں -
ڈائریکٹری → انسٹینز
-
ایک ذاتی سروے ایڈز کو وسائل کے انسٹینز کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کرسکتے ہیں)
-
ایک سروے پر صارفین کو کردار ادا کریں (مثال کے طور پر user123
creator
ہے poll456
)
ڈائریکٹری میں جائیں → انسٹینز
ڈائریکٹری میں جائیں → Instances
ڈائریکٹری → انٹرفیسز نوعی سروے ایڈز کو وسائل کے انسٹال کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کریں گے)
نوعی سروے ایڈز کو وسائل کے انسٹال کے طور پر شامل کریں (آپ نئے سروے پیدا ہونے کے بعد اس کو خود کار طریقے سے کرسکتے ہیں)
ایک سروے پر صارفین کو کردار ادا کریں (مثال کے طور پر user123
creator
ہے poll456
)
ایک سروے پر صارفین کو کردار ادا کریں (مثال کے طور پر user123
creator
کے poll456
)
user123
creator
poll456
اس ساخت نے ہمیں فکسڈ رسائی کے قوانین کو لکھنے اور ان کو ہر صارف، ہر سروے پر لاگو کرنے کی صلاحیت دی ہے۔
Now that we have completed the initial setup on the Permit dashboard, let's use it in our application. Next, we’ll connect Permit.io to our Supabase project via Edge Functions that:
Permit.io - نئی صارفین کو سنک کریں
- Creator roles کا تعین کریں
- Check access on demand
Sync نئے صارفین Creator Roles کا تعین کریں استعمال کی درخواست پر چیک کریں پولنگ ایپلی کیشن میں اجازت مقرر کرنا
Polling Application میں Permit کی ترتیباتPermit offers multiple ways to integrate with your application, but we'll use the Container PDP for this tutorial. You have to host the container online to access it in Supabase Edge functions. You can use services like railway.com. Once you have hosted it, save the url for your container.
railway.com
آپ کی اجازت API کلید حاصل کرنے کے لۓ اجازت ڈسپلے بیل میں "Projects" پر کلک کریں، آپ کے کام کر رہے ہیں کہ منصوبے پر پلگ ان کریں، تین پوائنٹس پر کلک کریں، اور "Copy API Key" کا انتخاب کریں.
آپوریشن کے لئے Supabase Edge Function API کی تخلیق
Supabase Edge Functions تیسری پارٹی کی خدمات جیسے Permit.io کو منسلک کرنے کے لئے بہترین ہیں.
ہم ان کا استعمال کریں گے کہ صارفین کو سروے پر مخصوص کارروائیوں کو انجام دینے کی اجازت ہے.
Supabase Edge FunctionsSupabase میں افعال پیدا کریں
Supabase میں فائلوں کا تخلیقاپنے منصوبے میں Supabase کو ابتدائی کریں اور supabase کے افعال نئے
کمانڈ کا استعمال کرتے ہوئے تین مختلف افعال پیدا کریں.supabase functions new
npx supabase init npx supabase Functions new syncUser npx supabase Functions new updateCreatorRole npx supabase Functions new checkPermission
npx supabase init
npx supabase functions new syncUser
npx supabase functions new updateCreatorRole
npx supabase functions new checkPermission
یہ ایک Functions
فارم پیدا کرے گا supabase
فارم کے ساتھ ساتھ آخر نقطہ. اب، ہم ہر آخر نقطہ کے لئے کوڈ لکھیں.
functions
supabase
Syncing Users to Permit.io on Signup (syncUser.ts
)
syncUser.ts
یہ فورم Supabase کے SIGNED_UP
auth واقعے کے لئے سنتا ہے۔ جب ایک نیا صارف سائن اپ کرتا ہے تو ہم ان کی شناخت کو Permit.io میں سائن اپ کرتے ہیں اور ان کو معاوضہ authenticated
کردار فراہم کرتے ہیں.
SIGNED_UP
authenticated
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { Permit } from "npm:permitio";
const corsHeaders = {
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'Authorization, x-client-info, apikey, Content-Type',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE',
}
// Supabase Edge Function to sync new users with Permit.io
Deno.serve(async (req) => {
const permit = new Permit({
token: Deno.env.get("PERMIT_API_KEY"),
pdp: "<https://real-time-polling-app-production.up.railway.app>",
});
try {
const { event, user } = await req.json();
// Only proceed if the event type is "SIGNED_UP"
if (event === "SIGNED_UP" && user) {
const newUser = {
key: user.id,
email: user.email,
name: user.user_metadata?.name || "Someone",
};
// Sync the user to Permit.io
await permit.api.createUser(newUser);
await permit.api.assignRole({
role: "authenticated",
tenant: "default",
user: user.id,
});
console.log(`User ${user.email} synced to Permit.io successfully.`);
}
// Return success response
return new Response(
JSON.stringify({ message: "User synced successfully!" }),
{ status: 200, headers: corsHeaders },
);
} catch (error) {
console.error("Error syncing user to Permit: ", error);
return new Response(
JSON.stringify({
message: "Error syncing user to Permit.",
"error": error
}),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
}
});
Creator Role کا تعین (updateCreatorRole.ts
)
updateCreatorRole.ts
ایک بار جب ایک صارف نے ایک سروے تخلیق کی ہے تو، اس تقریب کو کہا جاتا ہے:
کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی رائٹ کاپی پرسٹ کو ایک نیا Permit.io وسائل انٹرفیس کے طور پر سائن اپ کریں
پرسٹ کو ایک نیا Permit.io وسائل انٹرفیس کے طور پر سائن اپ کریں
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : ایک صارف کو اس سروے کے لئے creator
کردار کا تعین کریں
creator
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : import "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { Permit } from "npm:permitio";
const corsHeaders = {
'Access-Control-Allow-Origin': "*",
'Access-Control-Allow-Headers': 'Authorization, x-client-info, apikey, Content-Type',
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE',
}
Deno.serve(async (req) => {
const permit = new Permit({
token: Deno.env.get("PERMIT_API_KEY"),
pdp: "<https://real-time-polling-app-production.up.railway.app>",
});
try {
const { userId, pollId } = await req.json();
// Validate input parameters
if (!userId || !pollId) {
return new Response(
JSON.stringify({ error: "Missing required parameters." }),
{ status: 400, headers: { "Content-Type": "application/json" } },
);
}
// Sync the resource (poll) to Permit.io
await permit.api.syncResource({
type: "polls",
key: pollId,
tenant: "default",
attributes: {
createdBy: userId
}
});
// Assign the creator role to the user for this specific poll
await permit.api.assignRole({
role: "creator",
tenant: "default",
user: userId,
resource: {
type: "polls",
key: pollId,
}
});
return new Response(
JSON.stringify({
message: "Creator role assigned successfully",
success: true
}),
{ status: 200, headers: corsHeaders },
);
} catch (error) {
console.error("Error assigning creator role: ", error);
return new Response(
JSON.stringify({
message: "Error occurred while assigning creator role.",
error: error
}),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
}
});
چیک کرنے کی اجازتیں (checkPermission.ts
)
checkPermission.ts
یہ فہرست گٹیکر کے طور پر کام کرتا ہے - یہ چیک کرتا ہے کہ کیا ایک صارف کو ایک مخصوص سروے پر ایک مخصوص کارروائی (create
، read
، update
، delete
) کرنے کی اجازت ہے.
create
read
update
delete
اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہ اس کا مطلب یہ ہے کہimport "jsr:@supabase/functions-js/edge-runtime.d.ts";
import { Permit } from "npm:permitio";
const corsHeaders = {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Headers":
"Authorization, x-client-info, apikey, Content-Type",
"Access-Control-Allow-Methods": "POST, GET, OPTIONS, PUT, DELETE",
};
Deno.serve(async req => {
const permit = new Permit({
token: Deno.env.get("PERMIT_API_KEY"),
pdp: "<https://real-time-polling-app-production.up.railway.app>",
});
try {
const { userId, operation, key } = await req.json();
// Validate input parameters
if (!userId || !operation || !key) {
return new Response(
JSON.stringify({ error: "Missing required parameters." }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}
// Check permissions using Permit's ReBAC
const permitted = await permit.check(userId, operation, {
type: "polls",
key,
tenant: "default",
// Include any additional attributes that Permit needs for relationship checking
attributes: {
createdBy: userId, // This will be used in Permit's policy rules
},
});
return new Response(JSON.stringify({ permitted }), {
status: 200,
headers: corsHeaders,
});
} catch (error) {
console.error("Error checking user permission: ", error);
return new Response(
JSON.stringify({
message: "Error occurred while checking user permission.",
error: error,
}),
{ status: 500, headers: { "Content-Type": "application/json" } }
);
}
});
ملکی ٹیسٹ
اپنے Supabase dev سرور کو مقامی طور پر کاموں کی جانچ پڑتال کرنے کے لئے شروع کریں:
npx supabase start npx supabase functions serve
npx supabase start
npx supabase functions serve
پھر آپ اپنے افعال پر کلک کرسکتے ہیں:
<http://localhost:54321/functions/v1/><function-name>
<http://localhost:54321/functions/v1/><function-name>
مثال کے لئے:
<http://localhost:54321/functions/v1/checkPermission>
<http://localhost:54321/functions/v1/checkPermission>
UI میں لائسنس چیکز کو شامل کریں
ابھی کہ ہم نے Permit.io کے ساتھ ہماری ذمہ داری منطق تخلیق کی ہے اور Supabase Edge Functions کے ذریعے اسے ظاہر کیا ہے، یہ اپلی کیشن کے اجزاء کے اندر ان چیکوں کو لاگو کرنے کا وقت ہے.
اس سیکشن میں، ہم ان افعال کو کال کرنے کے لئے اہم UI اجزاء کو اپ ڈیٹ کریں گے اور شرط سے صارف کے کارروائیوں کو اجازت دیں یا بلاک کریں گے جیسے ووٹنگ یا اجازت چیک پر مبنی سروے کا انتظام کریں گے.
NewPoll.tsx
: Poll Creation کے بعد Creator Role Assign
NewPoll.tsx
ایک سروے تخلیق کرنے اور اسے Supabase میں محفوظ کرنے کے بعد، ہم updateCreatorRole
افعال کو دعوت دیتے ہیں:
updateCreatorRole
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : Permit.io میں نئے سروے کو ایک وسائل کے طور پر سائن اپ کریں
Permit.io میں نئے سروے کو ایک وسائل کے طور پر سائن اپ کریں
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : ایک مخصوص سروے کے لئے موجودہ صارف کو creator
کردار کا تعین کریں
creator
: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (question.trim() && options.filter(opt => opt.trim()).length < 2) {
setErrorMessage("Please provide a question and at least two options.");
return;
}
try {
// Create the poll
const { data: poll, error: pollError } = await supabase
.from("polls")
.insert({
question,
expires_at: new Date(expiryDate).toISOString(),
created_by: user?.id,
creator_name: user?.user_metadata?.user_name,
})
.select()
.single();
if (pollError) {
console.error("Error creating poll:", pollError);
setErrorMessage(pollError.message);
return;
}
// Create the options
const { error: optionsError } = await supabase.from("options").insert(
options
.filter(opt => opt.trim())
.map(text => ({
poll_id: poll.id,
text,
}))
);
if (optionsError) {
console.error("Error creating options:", optionsError);
setErrorMessage(optionsError.message);
return;
}
// Update the creator role in Permit.io
const response = await fetch(
"<http://127.0.0.1:54321/functions/v1//updateCreatorRole>",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: user?.id,
pollId: poll.id,
}),
}
);
const { success, error } = await response.json();
if (!success) {
console.error("Error updating creator role:", error);
// Note: We don't set an error message here as the poll was still created successfully
}
setSuccessMessage("Poll created successfully!");
handleCancel();
} catch (error) {
console.error("Error in poll creation process:", error);
setErrorMessage("An unexpected error occurred while creating the poll.");
}
};
ViewPoll.tsx
: لائسنس کی بنیاد پر ووٹنگ کو محدود کریں
ViewPoll.tsx
ایک صارف کو ایک سروے پر ووٹ کرنے کی اجازت دینے سے پہلے، ہم checkPermission
تقریب کو فون کرتے ہیں تاکہ اس بات کو یقینی بنائیں کہ وہ create
کی اجازت ہے votes
وسائل پر.checkPermission
create
votes
"ایک تخلیقکار اپنے سروے پر ووٹ نہیں کر سکتا."
مقالات کا جائزہ لیں:
پرسٹ کرنے کی اجازت چیک کریں:
const [canVote, setCanVote] = useState(false); useEffect(() => {const checkPermission = async () => { اگر (!user Mediateca!query.id) واپسی; try {const response = await fetch("<http://127.0.1:54321/functions/v1/checkPermission>", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ userId: user.id, operation: "create", key: query.id, }), } {constated = await response.json(); CanVoteVote(permittedconst [canVote, setCanVote] = useState(false);
useEffect(() => {
const checkPermission = async () => {
if (!user || !query.id) return;
try {
const response = await fetch("<http://127.0.0.1:54321/functions/v1/checkPermission>", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: user.id,
operation: "create",
key: query.id,
}),
});
const { permitted } = await response.json();
setCanVote(permitted);
} catch (error) {
console.error("Error checking permission:", error);
setCanVote(false);
}
};
checkPermission();
}, [user, query.id]);
اگر صارف کی اجازت نہیں ہے تو ووٹ بٹن غیر فعال کریں:
اگر صارف کی اجازت نہیں ہے تو ووٹ بٹن غیر فعال کریں:
<button onClick={() => handleVote(option.id)} disabled={!user Mediateca !canVote}} className="w-full text-left p-4 rounded-md hover:bg-slate-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"> {option.text} </button>
<button
onClick={() => handleVote(option.id)}
disabled={!user || !canVote}}
className="w-full text-left p-4 rounded-md hover:bg-slate-100 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
{option.text}
</button>
اگر صارف کو ووٹ کرنے کی اجازت نہیں ہے تو ایک پیغام دکھائیں:
اگر صارف کو ووٹ کرنے کی اجازت نہیں ہے تو ایک پیغام دکھائیں:
{user && !canVote && ( <p className="mt-4 text-gray-600">آپ اپنے ووٹ پر ووٹ نہیں کر سکتے</p> )}
{user && !canVote && (
<p className="mt-4 text-gray-600">You cannot vote on your own poll</p>
)}
PollCard.tsx
: Control Access to Edit/Delete
PollCard.tsx
ہم نے بھی update
یا delete
کی اجازت اس سروے پر موجود ہے یا نہیں کی جانچ پڑتال کرکے سروے کے انتظام کے اقدامات کو محدود کر دیا ہے.
update
delete
آپ کے انتظام کی اجازتیں چیک کریں:
استعمال کی اجازتوں کی جانچ پڑتال کریں:
const [canManagePoll, setCanManagePoll] = useState(false); useEffect(() => {const checkPollPermissions = async () => { اگر (!user-language-typescript!poll.id) واپسی؛ چیک کریں { // دونوں edit اور delete permissions constedit [Response, deleteResponse] کے لئے چیک کریں، جسم: JSON.strifingy([f] userId: edit.id، operation: "http://127.0.1:54321/functions/v1/checkPermission>", { method: "POST", headers: {"Content-Type": "Application/json", body: JSON.const [canManagePoll, setCanManagePoll] = useState(false);
useEffect(() => {
const checkPollPermissions = async () => {
if (!user || !poll.id) return;
try {
// Check for both edit and delete permissions
const [editResponse, deleteResponse] = await Promise.all([
fetch("<http://127.0.0.1:54321/functions/v1/checkPermission>", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: user.id,
operation: "update",
key: poll.id,
}),
}),
fetch("/api/checkPermission", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
userId: user.id,
operation: "delete",
key: poll.id,
}),
}),
]);
const [{ permitted: canEdit }, { permitted: canDelete }] =
await Promise.all([editResponse.json(), deleteResponse.json()]);
// User can manage poll if they have either edit or delete permission
setCanManagePoll(canEdit || canDelete);
} catch (error) {
console.error("Error checking permissions:", error);
setCanManagePoll(false);
}
};
checkPollPermissions();
}, [user, poll.id]);
مطالبہ طور پر انتظام کے بٹن دکھائیں:
موضوعی طور پر کنٹرول بٹن دکھائیں:
مزید کریں
{user?.id === poll?.created_by && (
{user?.id === poll?.created_by && (
کے ساتھ:
{canManagePoll && ( <div className="flex justify-start gap-4 mt-4"> <button type="button" onClick={handleEdit}> </button> <button type="button" onClick={handleDelete}> </button> </div> )}
{canManagePoll && (
<div className="flex justify-start gap-4 mt-4">
<button type="button" onClick={handleEdit}>
</button>
<button type="button" onClick={handleDelete}>
</button>
</div>
)}
مجموعہ کا تجربہ کریں
ایک بار انضمام، آپ کو ایپ میں مندرجہ ذیل رویے دیکھنا چاہئے:
-
لوگ نکالنے والے صارفین سروے دیکھ سکتے ہیں لیکن بات چیت نہیں کرسکتے
-
آپ didn پیدا کرتے ہوئے سروے پر ووٹ کرسکتے ہیں
-
Creators cannot vote on their own polls
Only creators see edit/delete options on their polls
لوگ نکالنے والے صارفین سروے دیکھ سکتے ہیں لیکن بات چیت نہیں کرسکتے
لوگ نکالنے والے صارفین سروے دیکھ سکتے ہیں لیکن بات چیت نہیں کرسکتے
ایٹینٹیج شدہ صارفین ان سروے پر ووٹ کرسکتے ہیں جو وہ didn’t create
ایٹینٹیج شدہ صارفین ان سروے پر ووٹ کرسکتے ہیں جو وہ didn't create
کیا نہیں Creators cannot vote on their own polls
Creators cannot vote ان کے اپنے سروے پر
cannot vote میں نہیں جا سکتا نہیں صرف تخلیق کرنے والوں کو دیکھیں edit/delete اختیارات ان کے سروے
ایک ہی تخلیق کار اپنے سروے میں edit/delete اختیارات دیکھتا ہے
edit/delete کو ہٹا دیں
آپ کو براؤزر پر جانے کے ذریعے ایپلی کیشن کی تبدیلیوں کو دیکھنے کے قابل ہونا چاہئے۔ ہوم سکرین پر، صارفین کو موجودہ اور گذشتہ سروے کی فہرست دیکھی جا سکتی ہے، چاہے وہ لاگ ان کر رہے ہیں یا نہیں ہیں۔ تاہم، جب وہ ایک سروے پر کلک کرتے ہیں تو وہ سروے کی تفصیلات کو دیکھنے یا اس پر ووٹ نہیں کرسکتے ہیں۔ اس کے بجائے، انہیں لاگ ان کرنے کے لئے کہا جائے گا۔
ایک بار لاگ ان کرنے کے بعد، صارف نے سروے کی تفصیلات کو دیکھنے اور اس پر ووٹ کر سکتے ہیں. تاہم، اگر صارف نے سروے کا تخلیق کیا ہے تو، وہ اس پر ووٹ نہیں کر سکتے ہیں. وہ ایک پیغام دیکھیں گے جو ان کے اپنے سروے پر ووٹ نہیں کر سکتے ہیں.
تصویر
اس ٹیوٹوریل میں، ہم نے ایک حقیقی دنیا میں Next.js ایپلی کیشن میں Supabase تصدیق اور لائسنس کو کیسے لاگو کرنے کا تجربہ کیا.
Supabase تصدیق اور لائسنسNext.js کے بارے میںWe started by setting up Supabase Auth for login and signup, created a relational schema with Row Level Security, and added dynamic authorization logic using ReBAC.With the help of Supabase Edge Functions and a Policy Decision Point (PDP), we enforced permission checks directly from the frontend.
سائپ بیس آؤٹRebac سے رابطہ کریںSupabase Edge FunctionsPolicy Decision Point (PDP)
مجھے Supabase Auth اور انعطاف پذیر رسائی کنٹرول کے ساتھ مل کر، ہم یہ کر سکتے ہیں:
سائپ بیس آؤٹ - Email اور پاس ورڈ کے ذریعے صارفین کی تصدیق کریں
- تصدیق شدہ صارفین کے لئے ووٹنگ اور سروے کے انتظام کو محدود کریں
- Creators from voting on their own polls
- Assign and evaluate user roles based on relationships to data
Email اور پاس ورڈ کے ذریعے صارفین کی تصدیق کریں صارفین کے لئے ووٹنگ اور سروے کے انتظام کو محدود کریں Creators from voting on their own polls روکنے کے لئے اعداد و شمار کے ساتھ تعلقات کی بنیاد پر صارفوں کے کردار کا تعین کریں اور کا جائزہ لیں
یہ ترتیبات آپ کو ایپلی کیشنز کی تعمیر کے لئے ایک وسیع پیمانے پر بنیاد فراہم کرتی ہیں جو دونوں تصدیق اور اچھی طرح سے لائسنس کی ضرورت ہوتی ہے.
مزید پڑھیں
-
-
-
-
-
Permit.io ReBAC Guide
Permit + Authentication Providers
Permit + Authentication Providers
Permit Elements: Embedded UI for Role Management
Permit Elements: Embedded UI for Role Management
Data Filtering with Permit
Audit Logs
Got questions? Join our Slack community, where hundreds of developers are building and discussing authorization.
Slack communitySlack community