Tech Sharing

Tauri Project Practice: Implementation Schemes for Authorization Login in Client and Web

In cross-platform application development (such as Mind Elixir Client built on Tauri), how to smoothly obtain authorization from the Web side and complete the login for the application is often a common and important requirement. This article will summarize the two login implementation methods we explored in this Tauri project and share a very classic pitfall we encountered when developing on macOS.

Published on March 6, 2026
5 min read
Mind Elixir Team
TauriCustom Scheme

In cross-platform application development (such as Mind Elixir Client built on Tauri), how to smoothly obtain authorization from the Web side and complete the login for the application is often a common and important requirement. This article will summarize the two login implementation methods we explored in this Tauri project and share a very classic pitfall we encountered when developing on macOS.

Old Login Method: Local HTTP Server Communication (Legacy Solution)

At the beginning of the project, to solve the pain point of passing the token back from the Web side to the desktop side, we adopted the method of starting a local HTTP server for cross-application communication:

Implementation Principle

Through Tauri combined with Rust's axum framework, the desktop program will start a tiny local server in the background, listening to a specific port (like 127.0.0.1:6595). After the user finishes logging in within the browser (such as cloud.mind-elixir.com), the Web page directly sends a POST request with login parameters to this local interface:

// axum_router.rs
async fn login_handler(
    headers: HeaderMap,
    Query(params): Query<Params>,
    handle_clone: tauri::AppHandle,
) -> impl IntoResponse {
    let token = params.token;
    // After receiving the HTTP request, emit a global login event to Tauri's frontend
    let _ = handle_clone.emit("login", Login { token: token });

    // ...handle CORS response
}

Next, the React frontend listens to this global event to get the token and store it in local storage to complete the login:

// App.tsx
const unlisten = listen<{ token: string }>('login', async (e) => {
  localStorage.setItem('token', e.payload.token)
  await fetchData()
  toast.success('Login Successful')
})

Pros and Cons

  • Pros: The implementation logic is simple and straightforward, and it is very convenient to debug casually in the development environment (tauri dev) without system-level protocol registration.
  • Cons: This is a relatively heavy solution; it requires additionally occupying a port on the user's computer, and occasionally communication may fail due to strict browser Cross-Origin Resource Sharing (CORS) policies or the port being occupied; in addition, this solution cannot invoke application windows on the mobile side.

New Login Method: Custom Scheme / Deep Link

Since the local server faces the aforementioned potential risks and does not align with the new trend of deep system integration, we subsequently switched to a more elegant and native solution—Custom Scheme Login (such as invoking mind-elixir://).

Configuration and Implementation

  1. Introduce Plugins and Configuration: Enable the @tauri-apps/plugin-deep-link plugin and register our specific protocol header mind-elixir in tauri.conf.json:

    "plugins": {
      "deep-link": {
        // Mobile (iOS/Android) configuration
        "mobile": [
          {
            "scheme": ["mind-elixir"],
            "appLink": false
          }
        ],
        // Desktop configuration
        "desktop": {
          "schemes": ["mind-elixir"]
        }
      }
    }
    

    Note: The mobile configuration requires simultaneously writing into Android's AndroidManifest.xml (<data android:scheme="mind-elixir" />) and iOS's Info.plist (CFBundleURLSchemes).

  2. Desktop System Wake-up Support: At the initialization hook in src-tauri/src/lib.rs, we need to call explicit registration APIs for Windows and Linux users.

    #[cfg(any(windows, target_os = "linux"))]
    {
        use tauri_plugin_deep_link::DeepLinkExt;
        app.deep_link().register_all()?;
    }
    
  3. Frontend Receiving Requests: Upon receiving a protocol request (i.e., the webpage redirects to a deep link like mind-elixir://login?token=xxxx), use Tauri's API to parse the deep link and complete authorization. It needs to handle both fetching during the cold start phase (getCurrent()) and monitoring runtime wake-ups (onOpenUrl):

    import { onOpenUrl, getCurrent } from '@tauri-apps/plugin-deep-link'
    import { getCurrentWindow } from '@tauri-apps/api/window'
    import { isMobile } from './utils/platform' // Custom environment checking utility in the project
    
    const handleDeepLinkUrls = async (urls: string[]) => {
      if (!urls || urls.length === 0) return
    
      // [Different platform behavior handling]
      // On mobile (especially iOS/Android), clicking a Deep Link automatically switches/wakes up the corresponding App to the foreground.
      // But on desktop, after receiving a deep link event, the application window might still remain in the background, so we need to manually bring it up and focus it via window API.
      if (!isMobile()) {
        const win = getCurrentWindow()
        await win.show()
        await win.setFocus()
      }
    
      // Check the array for links starting with the specific protocol
      const loginUrl = urls.find((url) => url.startsWith('mind-elixir://login'))
      if (loginUrl) {
        const url = new URL(loginUrl)
        const token = url.searchParams.get('token')
        if (token) {
          localStorage.setItem('token', token)
          await fetchData()
          toast.success('Login Successful')
        }
      }
    }
    
    // Handle cold start
    getCurrent().then((urls) => {
      if (urls) handleDeepLinkUrls(urls)
    })
    // Handle being awakened by protocol during runtime
    onOpenUrl(handleDeepLinkUrls)
    

Utilizing this way, after the user verifies their login state via the browser, the browser will smoothly prompt whether to open the target app, resulting in an excellent experience.

Pitfall Guardian: macOS/Linux Custom Scheme Debugging Limitation

According to Tauri's official documentation, under macOS and Linux systems, Deep Links (Custom Schemes) do not work properly in development mode (tauri dev).

If you modify the scheme-based login code, please be sure to test it by running the packaged program (tauri build). This also highlights an advantage of the first HTTP communication scheme—it serves as the best debugging channel during the development phase where frequent packaging is unnecessary.