understanding-tauri-ipc

安装量: 41
排名: #17510

安装

npx skills add https://github.com/dchuk/claude-code-tauri-skills --skill understanding-tauri-ipc
Tauri Inter-Process Communication (IPC)
This skill covers Tauri's IPC system, including the brownfield and isolation patterns for secure communication between frontend and backend processes.
Overview
Tauri implements Inter-Process Communication using
Asynchronous Message Passing
. This enables isolated processes to exchange serialized requests and responses securely.
Why Message Passing?
Safer than shared memory or direct function access
Recipients can reject or discard malicious requests
Tauri Core validates all requests before execution
Prevents unauthorized function invocation
IPC Primitives
Tauri provides two IPC primitives:
Events
Direction
Bidirectional (Frontend <-> Tauri Core)
Type
Fire-and-forget, one-way messaging
Best for
Lifecycle events, state changes, notifications
Rust (emit to frontend):
use
tauri
::
{
AppHandle
,
Emitter
}
;
fn
emit_event
(
app
:
&
AppHandle
)
{
app
.
emit
(
"backend-event"
,
"payload data"
)
.
unwrap
(
)
;
}
Frontend (listen):
import
{
listen
}
from
'@tauri-apps/api/event'
;
const
unlisten
=
await
listen
(
'backend-event'
,
(
event
)
=>
{
console
.
log
(
'Received:'
,
event
.
payload
)
;
}
)
;
// Call unlisten() when done
Frontend (emit to backend):
import
{
emit
}
from
'@tauri-apps/api/event'
;
await
emit
(
'frontend-event'
,
{
data
:
'value'
}
)
;
Commands
Direction
Frontend -> Rust backend
Protocol
JSON-RPC-based abstraction
API
Similar to browser's
fetch()
API
Requirement
Arguments and return data must be JSON-serializable Rust command definition:

[tauri::command]

fn greet ( name : & str ) -> String { format! ( "Hello, {}!" , name ) } fn main ( ) { tauri :: Builder :: default ( ) . invoke_handler ( tauri :: generate_handler! [ greet ] ) . run ( tauri :: generate_context! ( ) ) . expect ( "error while running tauri application" ) ; } Frontend invocation: import { invoke } from '@tauri-apps/api/core' ; const greeting = await invoke ( 'greet' , { name : 'World' } ) ; console . log ( greeting ) ; // "Hello, World!" Async command with Result:

[tauri::command]

async fn read_file ( path : String ) -> Result < String , String

{ std :: fs :: read_to_string ( & path ) . map_err ( | e | e . to_string ( ) ) } IPC Patterns Tauri provides two IPC security patterns: Brownfield (default) and Isolation . Brownfield Pattern What It Is The brownfield pattern is Tauri's default IPC approach. It prioritizes compatibility with existing web frontend projects by requiring minimal modifications. When to Use Migrating existing web applications to desktop Rapid prototyping and development Applications with trusted frontend code Simple applications with limited IPC surface Why Use It Zero configuration required Minimal changes to existing web code Direct access to Tauri APIs Fastest development path Configuration Brownfield is the default. Explicit configuration is optional: { "app" : { "security" : { "pattern" : { "use" : "brownfield" } } } } Note: There are no additional configuration options for brownfield. Code Example Rust backend:

[tauri::command]

fn
process_data
(
input
:
String
)
->
Result
<
String
,
String
>
{
// Direct processing without isolation layer
Ok
(
format!
(
"Processed: {}"
,
input
)
)
}
Frontend:
import
{
invoke
}
from
'@tauri-apps/api/core'
;
// Direct invocation - no isolation layer
const
result
=
await
invoke
(
'process_data'
,
{
input
:
'test'
}
)
;
Security Considerations
Frontend code has direct access to all exposed commands
No additional validation layer between frontend and backend
Supply chain attacks in frontend dependencies could invoke commands
Rely on command-level validation in Rust
Isolation Pattern
What It Is
The isolation pattern intercepts and modifies
all
Tauri API messages from the frontend using JavaScript before they reach Tauri Core. A secure JavaScript application (the Isolation application) runs in a sandboxed iframe to validate and encrypt all IPC communications.
When to Use
Applications with many frontend dependencies
High-security requirements
Handling sensitive data or operations
Public-facing applications
When supply chain attacks are a concern
Why Use It
Protection against Development Threats:
Validates all IPC calls before execution
Catches malicious or unwanted frontend calls
Mitigates supply chain attack risks
Provides a checkpoint for all communications
Tauri recommends using isolation whenever feasible.
How It Works
Tauri's IPC handler receives a message from frontend
Message routes to the Isolation application (sandboxed iframe)
Isolation hook validates and potentially modifies the message
Message encrypts using AES-GCM with runtime-generated keys
Encrypted message returns to IPC handler
Encrypted message passes to Tauri Core for decryption and execution
Key Security Features:
New encryption keys generated on each application launch
Sandboxed iframe prevents isolation code manipulation
All IPC calls validated, including event-based APIs
Configuration
tauri.conf.json:
{
"app"
:
{
"security"
:
{
"pattern"
:
{
"use"
:
"isolation"
,
"options"
:
{
"dir"
:
"../dist-isolation"
}
}
}
}
}
Code Example
Directory structure:
project/
src/ # Main frontend
src-tauri/ # Rust backend
dist-isolation/
index.html
index.js
dist-isolation/index.html:
<!
DOCTYPE
html
>
<
html
lang
=
"
en
"
>
<
head
>
<
meta
charset
=
"
UTF-8
"
/>
<
title
>
Isolation Secure Script
</
title
>
</
head
>
<
body
>
<
script
src
=
"
index.js
"
>
</
script
>
</
body
>
</
html
>
dist-isolation/index.js:
window
.
TAURI_ISOLATION_HOOK
=
(
payload
)
=>
{
// Log all IPC calls for debugging
console
.
log
(
'IPC call intercepted:'
,
payload
)
;
// Return payload unchanged (passthrough)
return
payload
;
}
;
Validation example (index.js):
window
.
TAURI_ISOLATION_HOOK
=
(
payload
)
=>
{
// Validate command calls
if
(
payload
.
cmd
===
'invoke'
)
{
const
{
__tauriModule
,
message
}
=
payload
;
// Block unauthorized file system access
if
(
message
.
cmd
===
'readFile'
)
{
const
path
=
message
.
path
;
if
(
!
path
.
startsWith
(
'/allowed/directory/'
)
)
{
console
.
error
(
'Blocked unauthorized file access:'
,
path
)
;
return
null
;
// Block the request
}
}
// Validate specific commands
if
(
message
.
cmd
===
'deleteItem'
)
{
if
(
!
confirm
(
'Are you sure you want to delete this item?'
)
)
{
return
null
;
// User cancelled
}
}
}
return
payload
;
}
;
Comprehensive validation example:
const
ALLOWED_COMMANDS
=
[
'greet'
,
'read_config'
,
'save_settings'
]
;
const
BLOCKED_PATHS
=
[
'/etc/'
,
'/usr/'
,
'/System/'
]
;
window
.
TAURI_ISOLATION_HOOK
=
(
payload
)
=>
{
// Validate invoke commands
if
(
payload
.
cmd
===
'invoke'
)
{
const
commandName
=
payload
.
message
?.
cmd
;
// Whitelist approach
if
(
!
ALLOWED_COMMANDS
.
includes
(
commandName
)
)
{
console
.
warn
(
'Blocked unknown command:'
,
commandName
)
;
return
null
;
}
// Validate path arguments
const
args
=
payload
.
message
?.
args
||
{
}
;
if
(
args
.
path
)
{
for
(
const
blocked
of
BLOCKED_PATHS
)
{
if
(
args
.
path
.
startsWith
(
blocked
)
)
{
console
.
error
(
'Blocked access to protected path:'
,
args
.
path
)
;
return
null
;
}
}
}
}
// Validate event emissions
if
(
payload
.
cmd
===
'emit'
)
{
const
eventName
=
payload
.
event
;
// Add event validation as needed
}
return
payload
;
}
;
Performance Considerations
AES-GCM encryption overhead is minimal for most applications
Comparable to TLS encryption used in HTTPS
Key generation requires system entropy (handled seamlessly on modern systems)
Performance-sensitive applications may notice slight impact
Limitations
ES Modules do not load in sandboxed iframes on Windows
Scripts must be inlined during build time
External files must be embedded rather than referenced
Avoid bundlers for the isolation application
Best Practices
Keep it simple
Minimize isolation application dependencies
No bundlers
Skip ES Modules and complex build processes
Validate inputs
Verify IPC calls match expected parameters
Whitelist commands
Only allow known, safe commands
Log suspicious activity
Monitor for potential attacks
Apply to events
Validate events that trigger Rust code Pattern Comparison Aspect Brownfield Isolation Default Yes No Configuration None required Requires isolation app Security Basic Enhanced Validation Command-level only All IPC calls Encryption None AES-GCM Performance Fastest Slight overhead Complexity Simple Moderate Best for Trusted code, prototypes Production, sensitive apps Security Best Practices For Both Patterns Validate all inputs in Rust commands

[tauri::command]

fn process_file ( path : String ) -> Result < String , String

{ // Always validate paths if path . contains ( ".." ) || path . starts_with ( "/etc" ) { return Err ( "Invalid path" . into ( ) ) ; } // Process file... Ok ( "Done" . into ( ) ) } Use typed arguments

[derive(serde::Deserialize)]

struct CreateUserArgs { name : String , email : String , }

[tauri::command]

fn
create_user
(
args
:
CreateUserArgs
)
->
Result
<
(
)
,
String
>
{
// Type-safe argument handling
Ok
(
(
)
)
}
Limit exposed commands
Only expose necessary functionality
Use capability-based permissions
Configure permissions in
capabilities/
For Isolation Pattern
Keep isolation code minimal
Reduce attack surface
Avoid external dependencies
No npm packages in isolation app
Use strict validation
Whitelist over blacklist
Test thoroughly
Ensure validation catches edge cases Choosing a Pattern Use Brownfield when: Building internal tools Prototyping rapidly Frontend code is fully trusted Minimal security requirements Use Isolation when: Building public applications Handling sensitive user data Using many third-party frontend packages Security is a priority Compliance requirements exist When in doubt, prefer isolation for production applications.
返回排行榜