---
title: OAuth Authorize API
description: Mağaza için OAuth yetkilendirme URL'si oluşturup yetkilendirme akışını başlatan API'yi yazın.
---

- Önce `pages/api` klasörü içinde `oauth` adında bir klasör oluşturun.
- Ardından `pages/api/oauth` klasörü içinde `authorize.ts` adında bir dosya oluşturun.

Dosya yapınız şu şekilde olmalıdır:

```txt
pages/
  api/
    oauth/
      authorize.ts
```

Artık uygulamamızdaki ilk API'yi yazmaya hazırız. `authorize.ts` dosyasını açın ve aşağıdaki kodu yapıştırın.

```typescript title="File: pages/api/oauth/authorize.ts"
import type { NextApiRequest, NextApiResponse } from 'next';
import { createRouter } from 'next-connect';
import { OAuthAPI } from '@ikas/api-client';
import { ApiErrorResponse } from '@/globals/types';
import { config } from '@/globals/config';
import { RedisDB } from '@/lib/redis';

type AuthorizeApiRequest = {
  storeName: string;
};
type AuthorizeApiResponse = ApiErrorResponse;

const router = createRouter<NextApiRequest, NextApiResponse<AuthorizeApiResponse>>();

/**
 * This API creates an OAuth authorize URL and starts the authorization process to an ikas store
 */
router.get(async (req, res) => {
  try {
    // Validate if storeName exists on req.query
    if (!req.query.storeName) res.status(400).json({ statusCode: 400, message: 'storeName is required' });
    const { storeName } = req.query as AuthorizeApiRequest;

    // state is a dynamic variable that should be saved before starting authorization flow
    // and should be validated on callback. This is used to prevent CSRF attacks.
    const state = Math.random().toFixed(16);

    // save your state variable to a temporary key-value database like Redis, Memcached
    // or any other storage, so you can retrieve and validate on callback
    await RedisDB.state.set(state, state, 60);

    // OAuthAPI.getOAuthUrl generates a root url for your app by using given storeName
    const oauthUrl = OAuthAPI.getOAuthUrl({ storeName });

    // Create authorize url for ikas store and redirect to it
    const url = `${oauthUrl}/authorize?client_id=${config.appId}&redirect_uri=${config.callbackUrl}&scope=${config.scope}&state=${state}`;
    res.redirect(url);
    return;
  } catch (err: any) {
    console.error(err);
    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);
  },
});
```

### Kodun Açıklaması

```typescript
import type { NextApiRequest, NextApiResponse } from 'next';
import { createRouter } from 'next-connect';
import { ApiErrorResponse } from '@/globals/types';

type AuthorizeApiRequest = {
  storeName: string;
};
type AuthorizeApiResponse = ApiErrorResponse;

const router = createRouter<NextApiRequest, NextApiResponse<AuthorizeApiResponse>>();

router.get(async (req, res) => {
  // Validate if storeName exists on req.query
  if (!req.query.storeName) res.status(400).json({ statusCode: 400, message: 'storeName is required' });
  const { storeName } = req.query as AuthorizeApiRequest;
  // Your API handler code...
});
```

- API handler'ı oluşturmak için `next-connect` kütüphanesinin `createRouter` fonksiyonunu kullanıyoruz. Bu fonksiyon, HTTP metodlarını yönetmeyi ve API'nize middleware uygulamayı kolaylaştırır. Ayrıntılar için [bu bağlantıya](https://github.com/hoangvvo/next-connect) göz atabilirsiniz.
- Handler'ın üzerinde Request/Response type'larını da tanımlıyoruz. Böylece API'nin girdi ve çıktısı kolayca okunabilir. Bu type'ları client tarafında, isteği sunucuya göndermeden önce verileri hazırlarken de kullanacağız.
- Bu API, mağazanızın subdomain'i olan `storeName` query parametresini bekler. Örneğin mağazanıza `mystore.myikas.com` adresinden erişiyorsanız mağaza adınız `mystore` olmalıdır.

```typescript
// state is a dynamic variable that should be saved before starting authorization flow
// and should be validated on callback. This is used to prevent CSRF attacks.
const state = Math.random().toFixed(16);
// save your state variable to a temporary key-value database like Redis, Memcached
// or any other storage, so you can retrieve and validate on callback
await RedisDB.state.set(state, state, 60);
```

- Authorization code akışını başlatmak için 10 karakterden uzun bir `state` değişkenine ihtiyacımız var. Bunun için 16 ondalık basamaklı rastgele bir sayı üretiyoruz.
- Ardından OAuth callback handler'ında kontrol edebilmek için `state` değişkenini 60 saniyelik TTL ile RedisDB'ye kaydediyoruz.

```typescript
// OAuthAPI.getOAuthUrl generates a root OAuth API url for your app by using given storeName
const oauthUrl = OAuthAPI.getOAuthUrl({ storeName });
```

- `@ikas/api-client` kütüphanesindeki `OAuthAPI` class'ı, verilen `storeName` için kök OAuth API URL'sini döndüren `getOAuthUrl` adında bir helper fonksiyon içerir.

```typescript
// Create authorize url for ikas store and redirect to it
const url = `${oauthUrl}/authorize?client_id=${config.appId}&redirect_uri=${config.callbackUrl}&scope=${config.scope}&state=${state}`;
res.redirect(url);
return;
```

- Son olarak yukarıda oluşturduğumuz tüm değişkenlerle bir URL oluşturuyor ve bu URL'ye yönlendiriyoruz.
