Escribiendo Permisos de Plugins
El objetivo de este ejercicio es comprender mejor cómo se pueden crear permisos de plugins al escribir tu propio plugin.
Al final tendrás la capacidad de crear permisos sencillos para tus plugins. Tendrás un plugin de Tauri de ejemplo donde los permisos se autogeneran parcialmente y se crean a mano.
-
Crear un Plugin de Tauri
Sección titulada "Crear un Plugin de Tauri"En nuestro ejemplo usaremos la
clide Tauri para inicializar la estructura del código fuente de un plugin de Tauri. Asegúrate de haber instalado todos los Requisitos previos y verifica que tengas la CLI de Tauri en la versión correcta ejecutandocargo tauri info.La salida debería indicar que la versión de
tauri-clies2.x. Continuaremos en esta explicación paso a paso conpnpm, pero puedes elegir otro gestor de paquetes y reemplazarlo en los comandos según corresponda.Una vez que tengas instalada una versión reciente, puedes continuar y crear el plugin usando la CLI de Tauri.
Ventana de terminal mkdir -p tauri-learningcd tauri-learningcargo tauri plugin new testcd tauri-plugin-testpnpm installpnpm buildcargo build -
Crear un Nuevo Comando
Sección titulada "Crear un Nuevo Comando"Para mostrar algo práctico y sencillo, supongamos que nuestro comando escribe la entrada del usuario en un archivo dentro de nuestra carpeta temporal mientras agrega un encabezado personalizado al archivo.
Nombremos nuestro comando
write_custom_file, implementémoslo ensrc/commands.rsy agreguémoslo a nuestro constructor de plugin para exponerlo al frontend.Las utilidades del núcleo de Tauri autogenerarán permisos de tipo
allowydenypara este comando, así que no tenemos que preocuparnos por esto.La implementación del comando:
src/commands.rs use tauri::{AppHandle, command, Runtime};use crate::models::*;use crate::Result;use crate::TestExt;#[command]pub(crate) async fn ping<R: Runtime>(app: AppHandle<R>,payload: PingRequest,) -> Result<PingResponse> {app.test1().ping(payload)}#[command]pub(crate) async fn write_custom_file<R: Runtime>(user_input: String,app: AppHandle<R>,) -> Result<String> {std::fs::write(app.path().temp_dir().unwrap(), user_input)?;Ok("success".to_string())}Autogenerar permisos integrados para tu nuevo comando:
src/build.rs const COMMANDS: &[&str] = &["ping", "write_custom_file"];Estos permisos integrados serán generados automáticamente por el sistema de compilación de Tauri y estarán visibles en la carpeta
permissions/autogenerated/commands. Por defecto se creará un permisoenable-<command>ydeny-<command>. -
Exponer el Nuevo Comando
Sección titulada "Exponer el Nuevo Comando"El paso anterior consistió en escribir la implementación real del comando. A continuación, queremos exponerlo al frontend para que pueda ser consumido.
Configura el constructor de Tauri para generar el manejador de invocaciones que pase las peticiones IPC del frontend al comando recién implementado:
src/lib.rs pub fn init<R: Runtime>() -> TauriPlugin<R> {Builder::new("test").invoke_handler(tauri::generate_handler![commands::ping,commands::write_custom_file,]).setup(|app, api| {#[cfg(mobile)]let test = mobile::init(app, api)?;#[cfg(desktop)]let test = desktop::init(app, api)?;app.manage(test);// manage state so it is accessible by the commandsapp.manage(MyState::default());Ok(())}).build()}Expón el nuevo comando en el módulo frontend.
Este paso es esencial para que la aplicación de ejemplo importe correctamente el módulo del frontend. Esto se hace por conveniencia y no tiene impacto en la seguridad, ya que el manejador del comando ya está generado y el comando se puede invocar manualmente desde el frontend.
guest-js/index.ts import { invoke } from '@tauri-apps/api/core'export async function ping(value: string): Promise<string | null> {return await invoke<{value?: string}>('plugin:test|ping', {payload: {value,},}).then((r) => (r.value ? r.value : null));}export async function writeCustomFile(user_input: string): Promise<string> {return await invoke('plugin:test|write_custom_file',{userInput: user_input});}Asegúrate de que tu paquete esté compilado:
pnpm build -
Definir Permisos Predeterminados del Plugin
Sección titulada "Definir Permisos Predeterminados del Plugin"Como nuestro plugin debería exponer el comando
write_custom_filepor defecto, deberíamos agregar esto a nuestro permisodefault.toml.Agrega esto a nuestro conjunto de permisos predeterminados para permitir el nuevo comando que acabamos de exponer.
permissions/default.toml "$schema" = "schemas/schema.json"[default]description = "Default permissions for the plugin"permissions = ["allow-ping", "allow-write-custom-file"] -
Invocando el Comando de Prueba desde la Aplicación de Ejemplo
Sección titulada "Invocando el Comando de Prueba desde la Aplicación de Ejemplo"La estructura de directorios del plugin creado contiene una carpeta
examples/tauri-app, que tiene una aplicación Tauri lista para usar para probar el plugin.Dado que agregamos un nuevo comando, necesitamos modificar ligeramente el frontend para invocar nuestro nuevo comando en su lugar.
src/App.svelte <script>import Greet from './lib/Greet.svelte'import { ping, writeCustomFile } from 'tauri-plugin-test-api'let response = ''function updateResponse(returnValue) {response += `[${new Date().toLocaleTimeString()}]` + (typeof returnValue === 'string' ? returnValue : JSON.stringify(returnValue)) + '<br>'}function _ping() {ping("Pong!").then(updateResponse).catch(updateResponse)}function _writeCustomFile() {writeCustomFile("HELLO FROM TAURI PLUGIN").then(updateResponse).catch(updateResponse)}</script><main class="container"><h1>Welcome to Tauri!</h1><div class="row"><a href="https://vitejs.dev" target="_blank"><img src="/vite.svg" class="logo vite" alt="Vite Logo" /></a><a href="https://tauri.app" target="_blank"><img src="/tauri.svg" class="logo tauri" alt="Tauri Logo" /></a><a href="https://svelte.dev" target="_blank"><img src="/svelte.svg" class="logo svelte" alt="Svelte Logo" /></a></div><p>Click on the Tauri, Vite, and Svelte logos to learn more.</p><div class="row"><Greet /></div><div><button on:click="{_ping}">Ping</button><div>{@html response}</div></div><div><button on:click="{_writeCustomFile}">Write</button><div>{@html response}</div></div></main><style>.logo.vite:hover {filter: drop-shadow(0 0 2em #747bff);}.logo.svelte:hover {filter: drop-shadow(0 0 2em #ff3e00);}</style>Al ejecutar esto y presionar el botón "Write", deberías ver esto:
successY deberías encontrar un archivo
test.txten tu carpeta temporal que contiene un mensaje proveniente del comando del nuevo plugin implementado. 🥳
© 2026 Colaboradores de Tauri. CC-BY / MIT