Photo by Scott Webb on Unsplash

REACT ARCHITECTURE SERIES

React Proje Mimarisi 21— (Authorization III)

Daha önceden yetkilendirme modellerinden ve React CASL ile yetkilendirme işlemlerinden bahsetmiştim. Bu yazıda Yetkilerin(Permission)ların Nasıl Sunucudan Alınarak Client Dinamik Olarak Uygulandığından bahsedeceğim.

Frontend Development With JS
4 min readDec 17, 2023

--

Bu yazıya başlamadan önce konunun devamı için aşağıdaki blog yazılarını okumanızı öneririm.

Özetle AuthorizationI de yetkilendirme modellerinden, biz uygulamalarımızda hangi yetkilendirme modelini ve hangi kütüphaneyi kullandığımızdan bahsettim.

Routing seviyesinde Rollere Göre yetkilendirme yani bu sayfayı şu roldeki kişinin görmeye yetkisi olup olmamına göre uygulamanın sergilemesi gereken davranışları anlattım.

AuthorizationII de ise Rollere göre Task Management uygulamasındaki bazı aksiyonların (Create, Delete vb..) gösterilmesi ve gizlenmesini sağlayan mekanizmaları ekledik. Özetle sayfa seviyesinden, sayfa içerisindeki elemanların yetkilendirilmesine indik.

Bugünkü yazımızda ise yetkilendirmelerin tamamen sunucu tarafında veritabanında bulunan yetkilerin kullanılarak dinamik nasıl yapılabileceği üzerine durcağız.

İşleyiş mekanizması şu şekilde olacak

Öncelikle uygulamamız minimal bir Permission ile başlayacak, örneğin Home sayfasın login olabilen herkesin giriş yapabileceğine düşünerek ClientSide default Permission minimal yetkiler statik konulacak.

Login sonrasında kullanı JWTToken elde ettikten sonra kendisine ait Role ve Permission(Yetki) bilgilerini sunucudan çekecek ve bu bilgileri CASL üzerinden güncelleyerek Routing(Yönlendirme) ve Component Level(Bileşen Seviyesi) yetkilendirmenin gerçekleştirilebilmesini sağlayacağız.

Bu yazı için geliştirdiğim örnek te

https://onurdayibasi.dev/miniapp/permission-based-authorization-comp

farklı yetki guruplarını ilgili ekrana uyguladığımızda düğmelerden bazılarının gözükmediğini görebilirsiniz.

https://onurdayibasi.dev/miniapp/permission-based-authorization-comp

Bu örnekte AuthorizationI ve AuthorizationII blog yazılarımda anlattığım Actions, Resources, Roles ve bunların Permissions JS kodu kısmında olmaması lazım, çünkü bunlar dinamik gelecek.

Öncelikle Sunucu tarafında elde ettiğimiz veriler action,subject tuple array şeklinde olacak..

  const AdminAuthItems = [
{action: 'delete', subject: 'article'},
{action: 'create', subject: 'article'},
{action: 'update', subject: 'article'},
{action: 'read', subject: 'article'},
];

const UserAuthItems = [
{action: 'create', subject: 'article'},
{action: 'update', subject: 'article'},
{action: 'read', subject: 'article'},
];

const GuestAuthItems = [{action: 'read', subject: 'article'}];

Bunların CASL tarafında işletilebilmesi için önce Context ve bunların yetkisinin olup olmayacağını check edebileceğimiz Can bileşenine ihtiyacımız var

import {createContextualCan} from '@casl/react';
import {createContext} from 'react';

// ** Create Context
export const AbilityContext = createContext();

// ** Init Can Context
export const Can = createContextualCan(AbilityContext.Consumer);

Diğer bir konuda JSONlarımı verip Ability oluşturmamızı ve güncellememizi sağlayan utility fonksiyonlardır.

import {Ability, detectSubjectType} from '@casl/ability';

export function buildAbilityFor(authItems) {
const ability = new Ability(authItems, {
detectSubjectType: (subject) => (subject && subject.subject ? subject.subject : detectSubjectType(subject)),
});
return ability;
}

export function updateAbility(ability, authItems) {
ability.update(authItems);
return ability;
}

Öncelikle Provider Pattern yöntemi ile boş bir yetkilendirme seti oluşturup bunu ArticleTestPart bileşenine veriyoruz.

function ArticleMiniApp() {
return (
<AbilityContext.Provider value={buildAbilityFor([])}>
<div>
<ArticleTestPart />
</div>
</AbilityContext.Provider>
);
}

Bu bileşen içerisinde AuthButton içeren Action türünü ve Subject verdiğimiz kısım.

    <>
<h1>Create Article</h1>
<AuthButton title="Create" authAction={'create'} authSubject={'article'} />

<h1>Delete Article</h1>
<AuthButton title="Delete" authAction={'delete'} authSubject={'article'} />
</>

Peki AuthButton ekrana yetkilendirmeden dolayı render edilip edilmeyeceğine nasıl karar veriliyor. AuthButton bunu <Can .. ile Ability üzerinden kendisi kontrol ediyor…

import {Can} from './authorization/can';

export const AuthButton = (props) => {
return (
<div>
<div>{props.authAction}</div>
<div>{props.authSubject}</div>
<Can do={props.authAction} on={props.authSubject}>
<Button>{props.title}</Button>
</Can>
</div>
);
};

Özetle burada kendi bileşenlerinizi oluşturup bu ara katmanda CrossCut işleri (Yetkilendirme, i18n, l10n, theme) işlevleri bu seviyelerde gerçekleştirebilirsiniz. Aşağıdaki yazılarda Platform Components üzerinden bu konuları anlatmıştım

Şimdi gelelim farklı yetki gruplarını dinamik olarak uygulamaya. Burada PermissionSelector üzerinden sanki sunucudan farklı yetkileri alıp günceller gibi ilgili düğmelere basınca ekranda farklı yetkilerim işletilmesi sağlanır.

import React, {useContext} from 'react';

import {updateAbility} from './authorization/ability';
import {AbilityContext} from './authorization/can';

function PermissionSelector() {
const ability = useContext(AbilityContext);

const AdminAuthItems = [
{action: 'delete', subject: 'article'},
{action: 'create', subject: 'article'},
{action: 'update', subject: 'article'},
{action: 'read', subject: 'article'},
];

const UserAuthItems = [
{action: 'create', subject: 'article'},
{action: 'update', subject: 'article'},
{action: 'read', subject: 'article'},
];

const GuestAuthItems = [{action: 'read', subject: 'article'}];

return (
<>
<p>Please Click below link to See Authorization in different Roles</p>
<button onClick={() => updateAbility(ability, AdminAuthItems)}>Admin Permission</button>
<button onClick={() => updateAbility(ability, UserAuthItems)}>User Permission</button>
<button onClick={() => updateAbility(ability, GuestAuthItems)}>Guest Permission</button>
</>
);
}

export default PermissionSelector;

Yukarıdaki kodda her bir düğmede elde bulunan permission (AuthorizationItems), updateAbility fonksiyonu ile context tekrar güncellenir.

Okumaya Devam Et 😃

Bu yazının devamı veya yazı grubundaki(react-mimarisi) diğer yazılara erişmek için bu linke tıklayabilirsiniz.

--

--

No responses yet