---
title: Scope değişikliklerini yönetme
description: Uygulamanıza yeni yetkiler gerektiğinde mağazayı yeni scope'larla yeniden yetkilendirin.
---

Uygulamamıza eklediğimiz yeni bir özellik bazen yeni yetkiler gerektirebilir. Örneğin satıcının siparişlerini uygulamamızda listelemek ya da uygulamamız üzerinden bir siparişi güncellemek istediğimizde, siparişleri okumak için uygulamamızın `read_orders` scope'u ile, güncellemek için ise `write_orders` scope'u ile yetkilendirilmiş olması gerekir. OAuth scope'umuzu güncellemek için uygulamamızı yeniden yetkilendirmemiz ve satıcının uygulamamıza yeni yetkileri vermesi gerekir. Bunun için kullanıcıyı yeni scope ile `oauth/authorize` API'sine yönlendirmemiz gerekir.

## Yeniden Yetkilendirme Gerekip Gerekmediğini Kontrol Etme

Önce ikas'taki mevcut scope'ları kontrol edip uygulamamızdaki yerel scope ile karşılaştıran yeni bir API oluşturacağız. Scope farklıysa bu API `state` ve `redirectUri` değişkenlerini oluşturur ve bunları yeni scope ile birlikte client tarafına döndürür.

- `pages/api/oauth` klasörü içinde `check-for-reauthorize.ts` adında bir dosya oluşturun ve aşağıdaki kodu yapıştırın.

```typescript
import type { NextApiRequest, NextApiResponse } from 'next';
import { createRouter } from 'next-connect';
import { ensureLoggedIn } from '@/lib/ensure-logged-in';
import { config } from '@/globals/config';
import { ApiErrorResponse } from '@/globals/types';
import { getIkas } from '@/lib/ikas-api';
import { RedisDB } from '@/lib/redis';

export type CheckForReauthorizeApiRequest = {};
export type CheckForReauthorizeApiResponse = {
  required: boolean;
  authorizeData?: {
    redirectUri: string;
    scope: string;
    state: string;
  };
};

const router = createRouter<NextApiRequest, NextApiResponse<CheckForReauthorizeApiResponse | ApiErrorResponse>>();

/**
 * This API checks if scope is different from scope granted by merchant
 */
router.use(ensureLoggedIn).get(async (req, res) => {
  try {
    const token = await RedisDB.token.get(req.user!.authorizedAppId);
    if (token) {
      const ikas = getIkas(token);
      // Get app info from ikas
      const meRes = await ikas.adminApi.queries.me({});
      if (meRes.isSuccess && meRes.data) {
        // Compare scopes
        if (meRes.data.scope != config.scope) {
          const state = Math.random().toFixed(16);
          await RedisDB.state.set(state, state, 60);
          // Return saved state and scope to client side
          res.status(200).json({
            required: true,
            authorizeData: {
              state,
              scope: config.scope,
              redirectUri: config.callbackUrl,
            },
          });
        }
      }
    }
    res.status(200).json({ required: false });
  } catch (err: any) {
    res.status(500).json({ statusCode: 500, message: err.message });
  }
});

export default router.handler({
  onError: (err: any, req, res) => {
    console.error(err.stack);
    res.status(err.statusCode || 500).end(err.message);
  },
});
```

### `api-requests.ts` Dosyasını Güncelleme

Client tarafında kullanabilmek için API'mizi `ApiRequests` objesine eklememiz gerekiyor.

- `api-requests.ts` dosyasını açın ve `ApiRequests` objesini aşağıdaki kodla güncelleyin:

```typescript
export const ApiRequests = {
  getTokenWithSignature: (data: GetTokenWithSignatureApiRequest) => makePostRequest<GetTokenWithSignatureApiResponse>({ url: '/api/get-token-with-signature', data }),
  oauth: {
    checkForReauthorize: (token: string) => makeGetRequest<CheckForReauthorizeApiResponse>({ url: '/api/oauth/check-for-reauthorize', token }),
  },
};
```

## `app/page.ts` Dosyasını Güncelleme

Şimdi yalnızca bu API'yi `load` fonksiyonunda çağırmamız ve yeniden yetkilendirme gerekiyorsa buna göre işlem yapmamız gerekiyor.

- `app/page.ts` dosyasını açın ve `load` fonksiyonunu aşağıdaki kodla güncelleyin:

```typescript
const load = async () => {
  AppBridgeHelper.closeLoader();
  const params = new URLSearchParams(window.location.search);
  // Retrieve token from session storage or from ikas via AppBridge
  let token = await TokenHelpers.getTokenForIframeApp(router);
  let isInternallyLoaded = false;
  if (token) {
    // If we received token this means app is loaded within ikas Dashboard
    isInternallyLoaded = true;
  } else {
    // App is not loaded in within ikas Dashboard try to load token via query params
    token = await TokenHelpers.getTokenForExternalApp(router, params);
  }
  if (token) {
    // If you successfully received token it is suggested checking if your app requires re-authorization
    const res = await ApiRequests.oauth.checkForReauthorize(token);
    const data = res.data as CheckForReauthorizeApiResponse | undefined;
    if (data?.required) {
      if (isInternallyLoaded) {
        // Call app bridge reaAuthorizeApp function so ikas dashboard will navigate to app grant access page
        AppBridgeHelper.reAuthorizeApp(data.authorizeData!);
      } else {
        // Redirect to authorize api
        window.location.replace(`/api/oauth/authorize?storeName=${params.get('storeName')}`);
      }
    } else {
      await router.push('/dashboard');
    }
  }
};
```

### Kodun Açıklaması

- Önce token'ı App Bridge ile almaya çalışıyoruz. Alabilirsek `isInternallyLoaded` değerini `true` yapıyoruz, alamazsak `getTokenForExternalApp` ile almayı deniyoruz.
- Token'ı aldıktan sonra `/api/oauth/check-for-reauthorize` API'sini çağıran `ApiRequests.oauth.checkForReauthorize` fonksiyonunu çağırıyoruz.
- `data.required=true` dönerse, uygulamamız ikas içinde yüklenmişse `AppBridgeHelper.reAuthorizeApp` fonksiyonunu çağırıyoruz, aksi halde `/api/oauth/authorize` API'sine yönlendiriyoruz.
- Ardından ikas Dashboard'da yeni yetkileri onaylamanız istenir. Yeni scope'ları kabul ettikten sonra tekrar `/api/oauth/callback` API'sine yönlendirilirsiniz.
