# 권한 제어

- Human documentation: [https://docs.univer.ai/ko-KR/guides/sheets/features/core/permission](https://docs.univer.ai/ko-KR/guides/sheets/features/core/permission)

- Agent Markdown: [https://docs.univer.ai/ko-KR/guides/sheets/features/core/permission.md](https://docs.univer.ai/ko-KR/guides/sheets/features/core/permission.md)

- Requested language: `ko-KR`

- Content language: `ko-KR`

- Documentation version: `1.0.4`

- Source: [sheets/features/core/permission.ko-KR.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/core/permission.ko-KR.mdx)

---

Univer는 통합 문서, 워크시트, 범위에서 사용자가 수행할 수 있는 작업을 제한하는 권한 제어 기능을 제공합니다. 사용자가 필요한 권한 없이 작업을 시도하면 실행을 중단하고 사용자에게 알립니다. 예를 들어 범위를 보호하여 공동 작업자가 해당 범위에서 편집, 보기, 복사 또는 필터링을 할 수 있는지 제어할 수 있습니다.

> [!WARNING]
> 서비스는 보호 규칙과 공동 작업자 변경을 저장하고 현재 사용자의 권한을 반환하며 요청 실패를 호출자에게 전달해야 합니다. 빈 목록을 반환하는 모의 구현은 영속성을 제공하지 않습니다. 공동 편집 시 백엔드는 읽기, JOIN, 변경 권한을 각각 검증해야 합니다. [신원 및 권한](https://docs.univer.ai/ko-KR/server/collaboration/identity-and-authorization.md)을 참고하세요. UI 보호와 음영 숨김은 서버 권한 검증을 대체하지 않습니다.
> 
> [권한 서비스 연동](#authorization-service)

> Interactive example: [Open the playground](/playground/sheets/permission)

아래에서 작업에 맞는 섹션으로 이동하세요. 기본 작업, 고급 예제, 설정과 문제 해결은 이 페이지에 모아 두고 전체 API 정의는 Reference에서 관리합니다.

* [일반적인 작업](#permission-tasks)
* [권한 UI 설정](#permission-ui)
* [권한 서비스 연동](#permission-integration)
* [Reference](#reference)

## 핵심 개념

* 적용 범위: 권한은 통합 문서, 워크시트, 범위의 세 수준에 적용됩니다.
* 권한 포인트: 각 기능은 하나의 권한 포인트에 대응합니다. 포인트를 변경하면 해당 기능을 사용할 수 있는지 제어할 수 있습니다.
* 보호 규칙: 워크시트와 범위의 권한 포인트를 설정하려면 먼저 보호 규칙을 만들어야 합니다.

> [!INFO]
> 영속성이 필요 없는 로컬 권한은 권한 포인트로 변경할 수 있습니다. 영속성 연동은 다음을 참고하세요: [권한 서비스 연동](#authorization-service)
> 
> 공동 편집 환경에서 권한 포인트를 업데이트하면 서버 상태도 동기화됩니다.
> 
> * `false`: 해당 권한 포인트를 사용하려면 최소 `owner` 역할이 필요합니다.
> * `true`: 해당 권한 포인트를 사용하려면 최소 `reader` 역할이 필요합니다.

## 기본 예제

`allowedUsers` 예제를 사용하기 전에 `user1`과 `user2`를 권한 서비스가 반환하는 실제 공동 작업자 ID로 바꾸세요.

가장 일반적인 권한 설정 방법을 통합 문서, 워크시트, 범위의 세 수준으로 나누어 살펴보겠습니다.

### 통합 문서 권한 코드 예제

통합 문서 수준 권한은 [Facade API](https://docs.univer.ai/ko-KR/guides/sheets/getting-started/facade.md)로 직접 설정할 수 있습니다.

다음 예제는 통합 문서 전체의 편집을 비활성화합니다. 다른 기능을 제어하려면 권한 포인트를 알맞게 바꾸세요([통합 문서 권한 포인트 목록](#workbook-point) 참고).

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// Set the workbook to be non-editable
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)
```

핵심 사항:

* 통합 문서 권한 포인트는 보호 규칙을 만들지 않고 직접 설정할 수 있습니다.

### 워크시트 권한 코드 예제

워크시트와 범위 권한은 Facade API 또는 명령으로 설정할 수 있습니다. 다음 예제에서는 워크시트 편집 권한을 설정합니다. 다른 기능을 제어하려면 권한 포인트를 알맞게 바꾸세요([워크시트 권한 포인트 목록](#worksheet-point) 참고).

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Create worksheet protection, allow specified users to edit
const permissionId = await worksheetPermission.protect({
  allowedUsers: ['user1', 'user2'],
  name: 'My Worksheet Protection',
})

// To set permission points, you must first protect the worksheet
await worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)
```

#### 워크시트 권한 삭제

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Remove worksheet protection
await worksheetPermission.unprotect()
```

### 사용자 정의 범위 권한 코드 예제

범위 권한도 API와 명령 방식으로 설정할 수 있습니다. 여기서는 범위 편집 권한을 예로 사용합니다. 다른 범위 기능을 제어하려면 권한 포인트를 바꿔야 합니다. 자세한 내용은 [권한 포인트 목록 - 범위](#range-point)를 참고하세요.

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// Set range protection permission, allow specified users to edit but not allow others to view
const rule = await rangePermission.protect({
  name: 'My protected range',
  allowViewByOthers: false,
  allowedUsers: ['user1', 'user2'],
})
console.log(rule)

// To set permission points, you must first create a range protection rule.
await rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)
await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)
```

#### 범위 보호 권한 삭제

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// delete all rules within the range
await rangePermission.unprotect()

// Or delete specific rules within the range
const rules = await rangePermission.listRules()
if (rules.length > 0) {
  await rules[0].remove()
}
```

## 일반적인 작업

### 통합 문서를 읽기 전용으로 설정

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const permission = fWorkbook.getWorkbookPermission()
await permission.setMode('viewer')
console.log(permission.getSnapshot())
```

### 보호 범위 관리

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const fWorksheet = fWorkbook.getActiveSheet()
const permission = fWorksheet.getWorksheetPermission()

const createdRules = await permission.protectRanges([
  {
    ranges: [fWorksheet.getRange('A1:B2')],
    options: { name: 'Public area', allowViewByOthers: true },
  },
  {
    ranges: [fWorksheet.getRange('C3:D4')],
    options: { name: 'Private area', allowViewByOthers: false, allowedUsers: ['user1'] },
  },
])
console.log(createdRules)

const rules = await permission.listRangeProtectionRules()
const firstRule = rules[0]
if (firstRule) {
  await firstRule.updateRanges([fWorksheet.getRange('A1:B3')])
}
```

### 셀 권한 진단

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const permission = fWorkbook.getActiveSheet().getWorksheetPermission()
console.log(permission.debugCellPermission(0, 0))
```

## 권한 포인트 목록

모든 권한 포인트의 소스 코드는 [여기](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point)에서 확인할 수 있습니다.

통합 문서 권한이 워크시트 또는 범위 권한과 겹치는 경우, 관련된 **모든** 권한을 `true`로 설정해야 해당 기능을 사용할 수 있습니다.

### 통합 문서 권한

| API 열거형                                                   | 해당 권한 포인트 클래스                        | 설명            |
| --------------------------------------------------------- | ------------------------------------ | ------------- |
| univerAPI.Enum.WorkbookPermissionPoint.Edit               | WorkbookEditablePermission           | 편집 가능         |
| univerAPI.Enum.WorkbookPermissionPoint.View               | WorkbookViewPermission               | 보기 가능         |
| univerAPI.Enum.WorkbookPermissionPoint.Print              | WorkbookPrintPermission              | 인쇄 가능         |
| univerAPI.Enum.WorkbookPermissionPoint.Export             | WorkbookExportPermission             | 내보내기 가능       |
| univerAPI.Enum.WorkbookPermissionPoint.Share              | WorkbookSharePermission              | 공유 가능         |
| univerAPI.Enum.WorkbookPermissionPoint.CopyContent        | WorkbookCopyPermission               | 복사 가능         |
| univerAPI.Enum.WorkbookPermissionPoint.DuplicateFile      | WorkbookDuplicatePermission          | 복제 가능         |
| univerAPI.Enum.WorkbookPermissionPoint.Comment            | WorkbookCommentPermission            | 댓글 작성 가능      |
| univerAPI.Enum.WorkbookPermissionPoint.ManageCollaborator | WorkbookManageCollaboratorPermission | 공동 작업자 관리 가능  |
| univerAPI.Enum.WorkbookPermissionPoint.CreateSheet        | WorkbookCreateSheetPermission        | 워크시트 생성 가능    |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteSheet        | WorkbookDeleteSheetPermission        | 워크시트 삭제 가능    |
| univerAPI.Enum.WorkbookPermissionPoint.RenameSheet        | WorkbookRenameSheetPermission        | 워크시트 이름 변경 가능 |
| univerAPI.Enum.WorkbookPermissionPoint.MoveSheet          | WorkbookMoveSheetPermission          | 워크시트 이동 가능    |
| univerAPI.Enum.WorkbookPermissionPoint.HideSheet          | WorkbookHideSheetPermission          | 워크시트 숨기기 가능   |
| univerAPI.Enum.WorkbookPermissionPoint.CopySheet          | WorkbookCopySheetPermission          | 워크시트 복사 가능    |
| univerAPI.Enum.WorkbookPermissionPoint.ViewHistory        | WorkbookViewHistoryPermission        | 기록 보기 가능      |
| univerAPI.Enum.WorkbookPermissionPoint.RecoverHistory     | WorkbookRecoverHistoryPermission     | 기록 복구 가능      |
| univerAPI.Enum.WorkbookPermissionPoint.CreateProtection   | WorkbookCreateProtectPermission      | 보호 설정 가능      |
| univerAPI.Enum.WorkbookPermissionPoint.InsertRow          | WorkbookInsertRowPermission          | 행 삽입 가능       |
| univerAPI.Enum.WorkbookPermissionPoint.InsertColumn       | WorkbookInsertColumnPermission       | 열 삽입 가능       |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteRow          | WorkbookDeleteRowPermission          | 행 삭제 가능       |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteColumn       | WorkbookDeleteColumnPermission       | 열 삭제 가능       |

### 워크시트 권한

| API 열거형                                                        | 해당 권한 포인트 클래스                             | 설명              |
| -------------------------------------------------------------- | ----------------------------------------- | --------------- |
| univerAPI.Enum.WorksheetPermissionPoint.Edit                   | WorksheetEditPermission                   | 편집 가능           |
| univerAPI.Enum.WorksheetPermissionPoint.View                   | WorksheetViewPermission                   | 보기 가능           |
| univerAPI.Enum.WorksheetPermissionPoint.Copy                   | WorksheetCopyPermission                   | 복사 가능           |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellValue           | WorksheetSetCellValuePermission           | 셀 값 편집 가능       |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellStyle           | WorksheetSetCellStylePermission           | 셀 스타일 편집 가능     |
| univerAPI.Enum.WorksheetPermissionPoint.SetRowStyle            | WorksheetSetRowStylePermission            | 행 스타일 설정 가능     |
| univerAPI.Enum.WorksheetPermissionPoint.SetColumnStyle         | WorksheetSetColumnStylePermission         | 열 스타일 설정 가능     |
| univerAPI.Enum.WorksheetPermissionPoint.InsertRow              | WorksheetInsertRowPermission              | 행 삽입 가능         |
| univerAPI.Enum.WorksheetPermissionPoint.InsertColumn           | WorksheetInsertColumnPermission           | 열 삽입 가능         |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteRow              | WorksheetDeleteRowPermission              | 행 삭제 가능         |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteColumn           | WorksheetDeleteColumnPermission           | 열 삭제 가능         |
| univerAPI.Enum.WorksheetPermissionPoint.Sort                   | WorksheetSortPermission                   | 정렬 가능           |
| univerAPI.Enum.WorksheetPermissionPoint.Filter                 | WorksheetFilterPermission                 | 필터링 가능          |
| univerAPI.Enum.WorksheetPermissionPoint.PivotTable             | WorksheetPivotTablePermission             | 피벗 테이블 사용 가능    |
| univerAPI.Enum.WorksheetPermissionPoint.InsertHyperlink        | WorksheetInsertHyperlinkPermission        | 하이퍼링크 사용 가능     |
| univerAPI.Enum.WorksheetPermissionPoint.ManageCollaborator     | WorksheetManageCollaboratorPermission     | 공동 작업자 관리 가능    |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteProtection       | WorksheetDeleteProtectionPermission       | 보호 삭제 가능        |
| univerAPI.Enum.WorksheetPermissionPoint.EditExtraObject        | WorksheetEditExtraObjectPermission        | 추가 객체 편집 가능     |
| univerAPI.Enum.WorksheetPermissionPoint.SelectProtectedCells   | WorksheetSelectProtectedCellsPermission   | 보호된 셀 선택 가능     |
| univerAPI.Enum.WorksheetPermissionPoint.SelectUnProtectedCells | WorksheetSelectUnProtectedCellsPermission | 보호되지 않은 셀 선택 가능 |

### 범위 보호

| API 열거형                                                | 해당 권한 포인트 클래스                                  | 설명                  |
| ------------------------------------------------------ | ---------------------------------------------- | ------------------- |
| univerAPI.Enum.RangePermissionPoint.Edit               | RangeProtectionPermissionEditPoint             | 보호 범위 편집 가능         |
| univerAPI.Enum.RangePermissionPoint.View               | RangeProtectionPermissionViewPoint             | 보호 범위의 내용 보기 가능     |
| univerAPI.Enum.RangePermissionPoint.Delete             | RangeProtectionPermissionDeleteProtectionPoint | 보호 범위 삭제 가능         |
| univerAPI.Enum.RangePermissionPoint.ManageCollaborator | RangeProtectionPermissionManageCollaPoint      | 보호 범위의 공동 작업자 관리 가능 |

## 권한 UI 설정

### 보호 범위 음영 표시 전략

현재 사용자가 편집할 수 있는 보호 영역과 편집할 수 없는 보호 영역을 구분하려면 `non-editable`을 사용하세요. 편집 가능한 보호 영역의 음영은 숨겨지고, 편집 권한이 비활성화된 보호 영역의 음영은 유지됩니다. 볼 수 없는 보호 범위의 마스크도 유지됩니다.

이 설정은 범위 보호와 워크시트 보호의 표시를 제어합니다. 보호 규칙을 만들거나 편집·보기 권한을 변경하지 않으며, 보호되지 않은 영역에 음영을 추가하지도 않습니다. 먼저 위의 설명에 따라 보호 규칙과 현재 사용자의 권한을 설정하세요.

| 전략                  | 표시 동작                                        |
| ------------------- | -------------------------------------------- |
| `true` / `'always'` | 모든 보호 영역에 음영을 표시합니다(기본값).                    |
| `'non-editable'`    | 편집 가능한 보호 영역의 음영을 숨기고 편집 불가능한 영역의 음영은 유지합니다. |
| `'non-viewable'`    | 볼 수 없는 보호 영역에만 음영을 표시합니다.                    |
| `false` / `'none'`  | 모든 보호 음영을 숨깁니다. 권한 검사는 계속 적용됩니다.             |



초기화 시 설정하세요:

#### 플러그인 모드

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  protectedRangeShadow: 'non-editable',
})
```

#### 프리셋 모드

```typescript
createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeShadow: 'non-editable',
      },
    }),
  ],
})
```

API를 통해 동적으로 변경할 수도 있습니다.

아래 Facade API는 현재 Univer 인스턴스의 기존 워크북에 표시 전략을 적용합니다. 플러그인 모드에서는 먼저 `@univerjs/sheets-ui/facade`를 가져오세요. Sheets Core 프리셋에는 이 가져오기가 포함되어 있습니다.

```typescript
// Set to only show shadows for non-editable ranges
univerAPI.setProtectedRangeShadowStrategy('non-editable')

// Get the current protected range shadow display strategy
console.log(univerAPI.getProtectedRangeShadowStrategy())

// Subscribe to changes in the protected range shadow strategy
const subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => {
  console.log('Global strategy changed to:', strategy)
  // Update UI or perform other actions
})

// Later, unsubscribe to clean up
subscription.unsubscribe()
```

### 사용자 정의 사용자 컴포넌트

Univer의 기본 제공 사용자 선택기는 유연성이 제한적입니다. 더 복잡한 상황에서는 다음과 같이 사용자 정의 컴포넌트를 제공할 수 있습니다.

> [!NOTE]
> 사용자 정의 컴포넌트를 만드는 방법은 [사용자 지정 컴포넌트](https://docs.univer.ai/ko-KR/guides/sheets/ui/components.md)를 참고하세요.

#### 플러그인 모드

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  protectedRangeUserSelector: {
    /**
     * Custom component; must implement the `IPermissionDetailUserPartProps` interface.
     */
    component: CustomPermissionDetailUserPart,
    /**
     * The framework of the component. Must be passed correctly.
     */
    framework: 'react',
  },
})
```

#### 프리셋 모드

```typescript
const { univer } = createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeUserSelector: {
        /**
         * Custom component; must implement the `IPermissionDetailUserPartProps` interface.
         */
          component: CustomPermissionDetailUserPart,
          /**
           * The framework of the component. Must be passed correctly.
           */
          framework: 'react',
        },
      },
    }),
  ],
})
```

사용자 선택기의 변경 핸들러에서 `setSelectUserList()`를 호출하세요. 아래 React 예제는 선택을 지웁니다. `useDependency`는 컴포넌트 안에서 실행하고 서비스 상태는 클릭 후에만 갱신합니다. 나머지 선택기는 `IPermissionDetailUserPartProps`에 맞게 구현하세요.

#### 플러그인 모드

```tsx
import type { IPermissionDetailUserPartProps } from '@univerjs/sheets-ui'
import type { FC } from 'react'
import { SheetPermissionUserManagerService } from '@univerjs/sheets-ui'
import { useDependency } from '@univerjs/ui'

export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {
  const service = useDependency(SheetPermissionUserManagerService)
  const clearSelection = () => service.setSelectUserList([])

  return <button type="button" onClick={clearSelection}>선택한 사용자 지우기</button>
}
```

#### 프리셋 모드

```tsx
import type { IPermissionDetailUserPartProps } from '@univerjs/preset-sheets-core'
import type { FC } from 'react'
import { SheetPermissionUserManagerService, useDependency } from '@univerjs/preset-sheets-core'

export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {
  const service = useDependency(SheetPermissionUserManagerService)
  const clearSelection = () => service.setSelectUserList([])

  return <button type="button" onClick={clearSelection}>선택한 사용자 지우기</button>
}
```

### 권한 대화 상자 숨기기

```typescript
univerAPI.setPermissionDialogVisible(false)
```

## 권한 서비스 연동

### 확장 사용법

자체 플러그인에서 권한을 확인해야 할 때는 권한 포인트를 직접 조작할 수 있습니다.

다음 예제에서는 `WorkbookEditablePermission`을 사용하여 자체 플러그인에서 권한을 확인하는 방법을 보여 줍니다. 다른 권한 포인트도 같은 방식으로 사용할 수 있습니다.

```typescript
import { IPermissionService } from '@univerjs/core'
import { WorkbookEditablePermission } from '@univerjs/sheets'

class YourService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
  }

  setWorkbookNotEditable() {
    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, false)
  }

  setWorkbookEditable() {
    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, true)
  }
}
```

[권한 포인트 목록](#point-list)

### 권한 포인트 확장 방법

권한 포인트를 사용자 정의하려면 `IPermissionPoint`를 구현하고 권한 서비스에 등록하세요.

```typescript
import type { IPermissionPoint } from '@univerjs/core'
import { IPermissionService, PermissionStatus } from '@univerjs/core'
import { UnitAction, UnitObject } from '@univerjs/protocol'

export class CustomPermissionPoint implements IPermissionPoint {
  type = UnitObject.Unkonwn // your type
  subType = UnitAction.View // your subType
  status = PermissionStatus.INIT
  value = true // Default value
  id: string
  constructor(unitId: string, subUnitId: string, customId: string) {
    // The id must be unique within `IPermissionService`.
    this.id = `${unitId}.${subUnitId}.${customId}`
  }
}

class YourService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
    this._init()
  }

  _init() {
    this._permissionService.addPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id'))
  }
}

// How to use it elsewhere
class ConsumeService {
  constructor(@IPermissionService private _permissionService: IPermissionService) {
  }

  doSomething() {
    const point = this._permissionService.getPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)
    console.log(point?.value)
  }

  bindEvent() {
    // This returns an RxJS observable that lets you listen for permission changes
    const point$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)
    console.log(point$)
  }
}
```

### 타사 권한 부여 서비스 연동(고급)

애플리케이션에서 [IAuthzIoService](https://github.com/dream-num/univer/blob/dev/packages/core/src/services/authz-io/type.ts)를 구현하고 권한, 역할, 공동 작업자 메서드를 백엔드에 연결하세요. 아래 예제는 `./authorization-service`가 구현을 `YourAuthzService`로 내보낸다고 가정합니다. 통합 문서를 생성하기 전에 등록하고 다른 초기화 설정과 플러그인 등록은 유지하세요.

```typescript
import { IAuthzIoService, Univer } from '@univerjs/core'
import { YourAuthzService } from './authorization-service'

const univer = new Univer({
  override: [[IAuthzIoService, { useClass: YourAuthzService }]],
})
```

서비스는 보호 규칙과 공동 작업자 변경을 저장하고 현재 사용자의 권한을 반환하며 요청 실패를 호출자에게 전달해야 합니다. 빈 목록을 반환하는 모의 구현은 영속성을 제공하지 않습니다. 공동 편집 시 백엔드는 읽기, JOIN, 변경 권한을 각각 검증해야 합니다. [신원 및 권한](https://docs.univer.ai/ko-KR/server/collaboration/identity-and-authorization.md)을 참고하세요. UI 보호와 음영 숨김은 서버 권한 검증을 대체하지 않습니다.

![권한](https://raw.githubusercontent.com/dream-num/documentation/dev/content/guides/sheets/features/core/permission/permission-en.png)

### 공동 작업자 관리

> [!NOTE]
> 공동 작업자 관리는 앱의 사용자·ACL 모델과 권한 서비스에서 구현합니다. [Identity and authorization](https://docs.univer.ai/ko-KR/server/collaboration/identity-and-authorization.md)에 따라 읽기, JOIN, 수정을 보호하세요. 아래 프런트엔드 API에는 대응하는 권한 서비스 구현이 필요합니다.

* 공동 작업자 목록 가져오기

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

const collaborators = await workbookPermission.listCollaborators()
console.log(collaborators)
```

* 공동 작업자 추가

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// Add multiple collaborators at once
await workbookPermission.setCollaborators([
  {
    user: { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
    role: univerAPI.Enum.UnitRole.Editor,
  },
  {
    user: { userID: 'user2', name: 'Jane Smith', avatar: '' },
    role: univerAPI.Enum.UnitRole.Reader,
  },
])

// Add a single collaborator
await workbookPermission.addCollaborator(
  { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Editor,
)
```

* 공동 작업자 역할 업데이트

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

await workbookPermission.updateCollaborator(
  { userID: 'user1', name: 'John Doe Updated', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Reader,
)
```

* 공동 작업자 제거

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
if (!fWorkbook) throw new Error('No active workbook')
const workbookPermission = fWorkbook.getWorkbookPermission()

// Remove multiple collaborators
await workbookPermission.removeCollaborators(['user1', 'user2'])

// Remove a single collaborator
await workbookPermission.removeCollaborator('user1')
```

## Reference

* [FWorkbookPermission](https://docs.univer.ai/ko-KR/reference/facade/workbook-permission.md)
* [FWorksheetPermission](https://docs.univer.ai/ko-KR/reference/facade/worksheet-permission.md)
* [FRangePermission](https://docs.univer.ai/ko-KR/reference/facade/range-permission.md)
* [FRangeProtectionRule](https://docs.univer.ai/ko-KR/reference/facade/range-protection-rule.md)
