権限管理
Univer はブック・シート・セル範囲に対する権限制御機能を提供します。ユーザーが許可されていない操作を実行しようとすると、コード実行を停止し、権限不足を通知できます。たとえば、範囲保護(エリア保護)を設定し、その範囲内で他の共同編集者が編集 / 閲覧 / コピー / フィルター等を行えるかどうかを制御できます。
以下から目的のセクションへ進んでください。基本操作、応用例、設定、トラブルシューティングをこのページにまとめ、完全な API 定義は Reference で管理しています。
基本概念
- 範囲:権限の対象となる範囲。Univer ではワークブック、ワークシート、選区の 3 つの範囲がサポートされており、ユーザーはこれらの範囲に対して権限を設定できます。
- 権限ポイント:権限の対象となる機能点。各機能点は対応する権限ポイントクラスで表され、ユーザーはこれらのポイントを設定して特定の機能を制御できます。
- 保護ルール:ワークシートと選区の権限設定には、まず保護ルールを作成する必要があります。保護ルールは、特定のユーザーやユーザーグループに対して範囲内の操作を許可または禁止するためのルールです。
永続化しないローカル権限は権限ポイントで変更できます。永続化については次を参照してください: 権限サービスの統合
協同編集シナリオでは、権限ポイントの更新はサーバー側の状態も同期的に更新します:
- false:その権限ポイントには少なくとも
ownerロールが必要 - true:その権限ポイントには少なくとも
readerロールが必要
基本例
allowedUsers の例を使う前に、user1 と user2 を認可サービスが返す実際の共同編集者 ID に置き換えてください。
最も一般的な権限設定方法を、ワークブック、ワークシート、選区の 3 つのレベルで以下に示します。
ワークブック権限コード例
現状、ブックレベルの権限は API を通じて直接変更します。Univer は Facade API を提供しており、これを用いてブックの各機能に対する権限を設定できます。
編集権限を例にとると(他の機能の場合は、権限ポイントを置き換えるだけで済みます。詳細については、権限ポイントビット一覧 - ワークブックを参照してください)、次のコードを使用してワークブック全体を編集不可に設定できます:
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// ワークブックを編集不可に設定await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)重要な点:
- ブック権限ポイントは直接設定でき、保護ルールの作成は必要ありません。
ワークシート権限コード例
ワークシートおよび範囲に関連する権限は Facade API とコマンド両方で設定可能です。ここではワークシート編集権限を例とします。その他のワークシート機能は権限ポイントビット一覧 - ワークシートを参照してください。
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const worksheetPermission = fWorksheet.getWorksheetPermission()// ワークシート保護を作成し、指定したユーザーのみ編集可能に設定const permissionId = await worksheetPermission.protect({ allowedUsers: ['user1', 'user2'], name: 'My Worksheet Protection',})// 権限ポイントを設定する必要がある場合は、まずワークシート保護を作成する必要がありますawait worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)ワークシート権限の削除
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const worksheetPermission = fWorksheet.getWorksheetPermission()// ワークシート保護を削除しますawait worksheetPermission.unprotect()カスタム範囲権限コード例
範囲(Range)権限も API とコマンドの両方式で設定できます。ここでは範囲編集権限を例とします。他の範囲機能は権限ポイントビット一覧 - 範囲を参照してください。
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()// 指定したユーザーのみ編集可能、他のユーザーは閲覧不可const rule = await rangePermission.protect({ name: 'My protected range', allowViewByOthers: false, allowedUsers: ['user1', 'user2'],})console.log(rule)// 権限ポイントを設定する必要がある場合は、まず範囲保護を作成する必要がありますawait rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)範囲保護権限の削除
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()// スコープ内のすべての保護ルールを削除await rangePermission.unprotect()// または、指定されたルールを削除const rules = await rangePermission.listRules()if (rules.length > 0) { await rules[0].remove()}よく使う操作
ブックを読み取り専用にする
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const permission = fWorkbook.getWorkbookPermission()await permission.setMode('viewer')console.log(permission.getSnapshot())保護範囲を管理する
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')])}セルの権限を調べる
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const permission = fWorkbook.getActiveSheet().getWorksheetPermission()console.log(permission.debugCellPermission(0, 0))権限ポイントビット一覧
対象コードは次の code を参照してください。
ブック権限とワークシート/範囲権限が交差する場合、利用には全て 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' | すべての保護シャドウを非表示にします。権限チェックは引き続き有効です。 |
保護シャドウのプレビュー
戦略を切り替えて、現在のユーザーに同じ領域がどう表示されるか比較できます。
保護なし
シャドウなし
保護あり・編集可
シャドウなし
保護あり・読み取り専用
シャドウあり
保護あり・閲覧不可
シャドウあり
これは表示の模式図です。シャドウを変えても権限は変わりません。none を選んでも閲覧できない内容は表示されません。
初期化時に設定します:
univer.registerPlugin(UniverSheetsUIPlugin, { protectedRangeShadow: 'non-editable',})createUniver({ presets: [ UniverSheetsCorePreset({ sheets: { protectedRangeShadow: 'non-editable', }, }), ],})API 経由で動的に変更も可能です:
以下の Facade API は、現在の Univer インスタンス内の既存のワークブックを更新します。プラグインモードでは、事前に @univerjs/sheets-ui/facade をインポートしてください。Sheets Core プリセットにはこのインポートが含まれています。
// 編集不可範囲の影のみ表示に設定univerAPI.setProtectedRangeShadowStrategy('non-editable')// 現在の保護範囲影表示戦略を取得console.log(univerAPI.getProtectedRangeShadowStrategy())// 保護範囲影表示戦略の変更を監視const subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => { console.log('Global strategy changed to:', strategy) // UIの更新や他のアクションを実行})// 後で購読解除subscription.unsubscribe()カスタムユーザーコンポーネント
Univer の標準ユーザーコンポーネントは適応性に限界があります。より複雑なカスタムコンポーネントが必要な場合は以下の方法で作成できます。
カスタムコンポーネントの作り方は Custom Components を参照してください。
univer.registerPlugin(UniverSheetsUIPlugin, { protectedRangeUserSelector: { /** * カスタムコンポーネント。`IPermissionDetailUserPartProps` を実装 */ component: CustomPermissionDetailUserPart, /** * 利用フレームワーク */ framework: 'react', },})const { univer } = createUniver({ presets: [ UniverSheetsCorePreset({ sheets: { protectedRangeUserSelector: { /** * カスタムコンポーネント。`IPermissionDetailUserPartProps` インターフェースを実装すること */ component: CustomPermissionDetailUserPart, /** * コンポーネントのフレームワーク。正しく指定する必要あり */ framework: 'react', }, }, }), ],})ユーザー選択の変更ハンドラーから setSelectUserList() を呼び出します。この最小の React 例は選択をクリアします。useDependency はコンポーネント内で実行し、サービスの更新はクリック時だけ行います。選択 UI の残りは IPermissionDetailUserPartProps に従って実装してください。
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>}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>}権限ダイアログの非表示
univerAPI.setPermissionDialogVisible(false)権限サービスの統合
拡張利用
独自のプラグイン内で権限検証を追加する必要がある場合は、直接権限ポイントを操作できます。
ここでは WorkbookEditablePermission を例に、独自プラグイン内で権限検証を追加します。他のポイントも同様です。
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) }}権限ポイントの拡張方法
権限ポイントをカスタマイズする必要がある場合は、IPermissionPoint を実装し、権限サービスに登録できます。
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 // 任意のタイプ subType = UnitAction.View // 任意のサブタイプ status = PermissionStatus.INIT value = true // 初期値 id: string constructor(unitId: string, subUnitId: string, customId: string) { // id は 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')) }}// 他所での利用例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() { // これは Rx オブジェクトを取得し、権限変更を監視したりリストを更新したりできる const point$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id) console.log(point$) }}サードパーティ認可サービスの統合(高度な利用)
アプリで IAuthzIoService を実装し、権限・ロール・共同編集者の各メソッドをバックエンドに接続します。この例では ./authorization-service が実装を YourAuthzService として公開しているものとします。ブック作成前に登録し、他の初期化設定とプラグイン登録は保持してください。
import { IAuthzIoService, Univer } from '@univerjs/core'import { YourAuthzService } from './authorization-service'const univer = new Univer({ override: [[IAuthzIoService, { useClass: YourAuthzService }]],})保護ルールと共同編集者の変更を永続化し、現在のユーザーの権限を返し、リクエスト失敗を呼び出し元へ伝えてください。空リストを返すモックでは永続化できません。共同編集では、バックエンドが読み取り・JOIN・変更の権限を個別に検証する必要があります。ID と認可を参照してください。UI の保護やシャドウの非表示はサーバー認可の代替にはなりません。
共同編集者管理
共同編集者の管理はアプリのユーザー・ACL モデルと権限サービスで実装します。Identity and authorization に沿って読み取り、JOIN、編集を保護してください。以下のフロントエンド API には対応する権限サービスの実装が必要です。
- 共同編集者リストの取得
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()const collaborators = await workbookPermission.listCollaborators()console.log(collaborators)- 共同編集者の追加
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// 複数の共同編集者を一度に追加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, },])// 単一の共同編集者を追加await workbookPermission.addCollaborator( { userID: 'user1', name: 'John Doe', avatar: 'https://...' }, univerAPI.Enum.UnitRole.Editor,)- 共同編集者ロールの更新
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,)- 共同編集者の削除
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// 複数の共同編集者を一度に削除await workbookPermission.removeCollaborators(['user1', 'user2'])// 単一の共同編集者を削除await workbookPermission.removeCollaborator('user1')Reference
このガイドはいかがですか?