{"id":11647,"date":"2025-02-03T17:55:47","date_gmt":"2025-02-03T16:55:47","guid":{"rendered":"https:\/\/www.basyskom.de\/?p=11647"},"modified":"2025-02-06T08:05:31","modified_gmt":"2025-02-06T07:05:31","slug":"setting-up-flutter-and-grpc-with-tls-and-token-based-authentication","status":"publish","type":"post","link":"https:\/\/www.basyskom.de\/en\/setting-up-flutter-and-grpc-with-tls-and-token-based-authentication\/","title":{"rendered":"Setting up Flutter and gRPC with TLS and token-based authentication"},"content":{"rendered":"<div data-elementor-type=\"wp-post\" data-elementor-id=\"11647\" class=\"elementor elementor-11647\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d8e8efd e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-equal-height-no e-con e-parent\" data-id=\"d8e8efd\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-e05222f elementor-widget elementor-widget-heading\" data-id=\"e05222f\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Introduction<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b1bac02 elementor-widget elementor-widget-text-editor\" data-id=\"b1bac02\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In our recent article &#8220;State of Flutter on Embedded Linux&#8221; (see the\u00a0<a class=\"external-link\" href=\"https:\/\/www.basyskom.de\/en\/state-of-flutter-on-embedded-linux\/\" rel=\"nofollow\">blog post<\/a>), we described the state and advantages of using Flutter on embedded Linux systems. In a follow-up article (see the <a href=\"https:\/\/www.basyskom.de\/en\/flutter-on-embedded-hmi-mobile-apps-and-middleware\/\" rel=\"nofollow\">blog post<\/a>), we presented some architectural considerations and concrete ideas on how a respective system architecture could look. One possible building block of the architecture is gRPC, which can be used for communication between the client and the backend (see\u00a0<a class=\"external-link\" href=\"https:\/\/grpc.io\/\" rel=\"nofollow noopener\" target=\"_blank\">gRPC project website<\/a>). This enables a clean and strict separation of concerns. The HMI created with Flutter will run on mobile, desktop and embedded platforms.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a251db6 elementor-widget elementor-widget-text-editor\" data-id=\"a251db6\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In the context of the architecture described in the blog post, this article deals with the topic of security, which in most cases must be taken into account when communicating via networks. With gRPC you get a free (Apache License 2.0), high-performance and language-independent RPC framework that ensures the confidentiality, integrity and authenticity of the communicated data on the basis of HTTP\/2 and TLS.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-d3c928c elementor-widget elementor-widget-text-editor\" data-id=\"d3c928c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In this article, we use a minimal example to show how these technologies can be combined to have a platform-independent Flutter app communicating securely with a backend running on an embedded system via gRPC.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-cebdf7c elementor-widget elementor-widget-heading\" data-id=\"cebdf7c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">gRPC Support<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9762764 elementor-widget elementor-widget-text-editor\" data-id=\"9762764\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\tA basic requirement for the presented approach is that the language used for the backend supports gRPC. \t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c78d2cc elementor-widget elementor-widget-text-editor\" data-id=\"c78d2cc\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>As known from other RPC frameworks, gRPC comes with a compiler that transforms abstract interface definitions to code for the target language. For example, if you use C++ for the backend, the compiler provides you with C++ code for the client stubs, server skeletons and message types. As a basis for communication (locally or via networks), gRPC uses the project Protocol Buffers (&#8220;Protobuf&#8221;; see <a class=\"external-link\" href=\"https:\/\/protobuf.dev\/\" rel=\"nofollow noopener\" target=\"_blank\">project website<\/a>), which comes with Protocol Buffers Compiler (&#8220;protoc&#8221;). Protobuf interface definitions are described in an abstract language in <code data-no-translation=\"\">.proto<\/code> files. Along with a respective language plugin, the compiler uses the <code data-no-translation=\"\">.proto<\/code> files to generate the code in the target language. So gRPC support means there is a plugin for protoc and a library for generic gRPC functionality which is linked with your server application.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-69d6def elementor-widget elementor-widget-text-editor\" data-id=\"69d6def\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The range of supported languages is quite extensive (see <a class=\"external-link\" href=\"https:\/\/grpc.io\/docs\/languages\" rel=\"nofollow noopener\" target=\"_blank\">gRPC languages<\/a>). In addition, there are unofficial projects that are not listed here, such as tonic for rust (see <a class=\"external-link\" href=\"https:\/\/github.com\/hyperium\/tonic\" rel=\"nofollow noopener\" target=\"_blank\">project website<\/a>).<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-737c616 elementor-widget elementor-widget-text-editor\" data-id=\"737c616\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In our example we use the official Dart package (see <a class=\"external-link\" href=\"https:\/\/pub.dev\/packages\/grpc\" rel=\"nofollow noopener\" target=\"_blank\">package website<\/a>) for both client and server as well as the official Dart plugin for protoc (see <a class=\"external-link\" href=\"https:\/\/pub.dev\/packages\/protoc_plugin\" rel=\"nofollow noopener\" target=\"_blank\">plugin website<\/a>) to generate the code. All components at this point are developed and (at the time of writing) actively maintained by\u00a0Google.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ba1f9e2 elementor-widget elementor-widget-text-editor\" data-id=\"ba1f9e2\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In real projects, other languages such as C++ are more likely to be used for the backend, which can be more easily connected to existing libraries, interfaces and middleware on the target. But as described in the previous blog post, for network facing services the use of memory-safe languages should be considered to avoid security issues caused by widespread memory-management errors like buffer overflows and the like.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a9a55ae elementor-widget elementor-widget-heading\" data-id=\"a9a55ae\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Basic Idea<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3616c1c elementor-widget elementor-widget-text-editor\" data-id=\"3616c1c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The approach is very well established and well known from web technologies, where REST APIs, HTTP, TLS and access tokens are combined to implement secure communication between client and server. The rough procedure is:<\/p><ul><li>Users authenticate by providing their credentials over a TLS-secured channel.<\/li><li>If the user name and password are correct, the server provides <span class=\"inline-comment-marker\" data-ref=\"90ad9edc-9862-41b9-b626-110c90e9c780\">a token that the client uses for all subsequent requests (until the user logs out or the token is invalidated in some other way).\u00a0<\/span><\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-f7ae98b elementor-widget elementor-widget-text-editor\" data-id=\"f7ae98b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>There are two key points to implementing this approach:<\/p><ul><li>The communication between client and backend needs encryption. This is covered by using HTTP\/2 with TLS.<\/li><li>There is some kind of authority capable of issuing and verifying access tokens. For simple use cases, this can be implemented directly in the backend.<\/li><\/ul>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-a5b983c elementor-widget elementor-widget-text-editor\" data-id=\"a5b983c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In the following sections, we will show you how to put these parts together to create a minimal working app.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-9dfffff elementor-widget elementor-widget-heading\" data-id=\"9dfffff\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Project setup<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-997b581 elementor-view-default elementor-position-block-start elementor-mobile-position-block-start elementor-widget elementor-widget-icon-box\" data-id=\"997b581\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"icon-box.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-icon-box-wrapper\">\n\n\t\t\t\t\t\t<div class=\"elementor-icon-box-icon\">\n\t\t\t\t<a href=\"https:\/\/github.com\/basysKom\/example_flutter_grpc_security\" class=\"elementor-icon\" tabindex=\"-1\" aria-label=\"Find the example project in our GitHub\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t<svg aria-hidden=\"true\" class=\"e-font-icon-svg e-fab-github\" viewbox=\"0 0 496 512\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z\"><\/path><\/svg>\t\t\t\t<\/a>\n\t\t\t<\/div>\n\t\t\t\n\t\t\t\t\t\t<div class=\"elementor-icon-box-content\">\n\n\t\t\t\t\t\t\t\t\t<div class=\"elementor-icon-box-title\">\n\t\t\t\t\t\t<a href=\"https:\/\/github.com\/basysKom\/example_flutter_grpc_security\" target=\"_blank\" rel=\"noopener\">\n\t\t\t\t\t\t\tFind the example project in our GitHub\t\t\t\t\t\t<\/a>\n\t\t\t\t\t<\/div>\n\t\t\t\t\n\t\t\t\t\n\t\t\t<\/div>\n\t\t\t\n\t\t<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-95ccaa5 elementor-widget elementor-widget-text-editor\" data-id=\"95ccaa5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The example project is available <a href=\"https:\/\/github.com\/basysKom\/example_flutter_grpc_security\" target=\"_blank\" rel=\"noopener\">here<\/a> and consists of three parts:<\/p><ol><li>The Flutter app itself is the main project.<\/li><li>The demo backend is a Dart package in <code data-no-translation=\"\">packages\/test_server<\/code>.<\/li><li>The interface definitions and generated Dart sources are in the Dart package <code data-no-translation=\"\">packages\/grpc_interface<\/code>. This is used by the app and the backend.<\/li><\/ol>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b094487 elementor-widget elementor-widget-text-editor\" data-id=\"b094487\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In real-world projects, 1. and 2. would be separate projects of course. One aspect that needs to be considered and decided in real-world projects is where to place the interface definitions. For example, one could place them in a separate Git repository and add it as a submodule to both the client and the backend.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-051d094 elementor-widget elementor-widget-heading\" data-id=\"051d094\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Server<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-b93a12b elementor-widget elementor-widget-text-editor\" data-id=\"b93a12b\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>If you use gRPC, a server can be equipped with several services. This helps in particular to achieve a clear separation of concerns. In our demo case we have two services. The first (AuthService) is for authentication, the second (MachineService) is a placeholder for your business logic. Token validation is implemented by an interceptor for the gRPC server (see <code data-no-translation=\"\">authInterceptor<\/code>).<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ce471cf elementor-widget elementor-widget-text-editor\" data-id=\"ce471cf\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The services are defined in the already mentioned <code data-no-translation=\"\">.proto<\/code> interface definition files (see <code data-no-translation=\"\">authentication.proto<\/code> and <code data-no-translation=\"\">machine.proto<\/code>).<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c08941d elementor-widget elementor-widget-text-editor\" data-id=\"c08941d\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>A server certificate must be provided in order to use TLS encryption. In our demo project we generate this using openssl. What is important at this stage is that even the login process is encrypted, ensuring that no credentials are transmitted in plaintext.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-dd66377 elementor-widget elementor-widget-text-editor\" data-id=\"dd66377\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>For the access tokens, we use JWT. The server-side generation and verification of these tokens is handled by the Dart package <code data-no-translation=\"\">dart_jsonwebtoken<\/code> (see <a class=\"external-link\" href=\"https:\/\/pub.dev\/packages\/dart_jsonwebtoken\" rel=\"nofollow noopener\" target=\"_blank\">package website<\/a>).<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3b85dd1 elementor-widget elementor-widget-heading\" data-id=\"3b85dd1\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Flutter App<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-0406208 elementor-widget elementor-widget-text-editor\" data-id=\"0406208\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>There isn\u2019t much to say about the app. It is as minimal as possible to test the encrypted communication, authentication\/token retrieval, and token-based communication. One important thing to consider here is the difference between the client for the authentication service (used by the login screen) and the machine service (used by the home screen). While both require the certificate to securely communicate via TLS, only the machine service (understandably) needs to be equipped with a token.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-c786a4c elementor-widget elementor-widget-heading\" data-id=\"c786a4c\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Interface<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-416ce17 elementor-widget elementor-widget-text-editor\" data-id=\"416ce17\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>The <code data-no-translation=\"\">grpc_interface<\/code> package only contains the interface definitions and the generated Dart sources.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-17c37c5 elementor-widget elementor-widget-text-editor\" data-id=\"17c37c5\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In order to (re-)generate the Dart sources, protoc and the respective Dart plugin must be installed on the system. The compiler can then be used as follows to create the corresponding Dart sources from a .proto file:<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-77dd8db elementor-widget elementor-widget-elementor-syntax-highlighter\" data-id=\"77dd8db\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"elementor-syntax-highlighter.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<pre data-no-translation=\"\"><code class='language-bash' data-no-translation=\"\">protoc --dart_out=grpc:lib\/generated -Iproto proto\/authentication.proto -Iproto proto\/machine.proto <\/code><\/pre><script>\nif (!document.getElementById('syntaxed-prism')) {\n\tvar my_awesome_script = document.createElement('script');\n\tmy_awesome_script.setAttribute('src','https:\/\/www.basyskom.de\/wp-content\/plugins\/syntax-highlighter-for-elementor\/assets\/prism2.js');\n\tmy_awesome_script.setAttribute('id','syntaxed-prism');\n\tdocument.body.appendChild(my_awesome_script);\n} else {\n\twindow.Prism && Prism.highlightAll();\n}\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-69e97d4 elementor-widget elementor-widget-text-editor\" data-id=\"69e97d4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>This creates several Dart files, of which only two are currently of interest. <code data-no-translation=\"\">authentication.pb.dart<\/code> defines the protobuf message types (hence the &#8220;pb&#8221;) and\u00a0<code data-no-translation=\"\">authentication.pbgrpc.dart<\/code> provides the base classes <span class=\"inline-comment-marker\" data-ref=\"858673e3-a914-4a1c-a9e3-675d31faf00a\">for <\/span>the client (<code data-no-translation=\"\">GrpcAuthenticationClient<\/code>) and server (<code data-no-translation=\"\">GrpcAuthenticationServiceBase<\/code>). These are abstract and must be implemented in your client and server.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ba93fb9 elementor-widget elementor-widget-heading\" data-id=\"ba93fb9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"heading.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<h2 class=\"elementor-heading-title elementor-size-default\">Conclusion<\/h2>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-3fe0a88 elementor-widget elementor-widget-text-editor\" data-id=\"3fe0a88\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p><span class=\"inline-comment-marker active\" data-ref=\"64037390-98d4-4f61-8c04-edf5c30e26ed\">In this article, we have shown how little it takes to lay the foundation for a platform-independent application<\/span> that can run on various target systems and that communicates securely with a gRPC-based backend on your embedded system.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-19eb5e9 elementor-widget elementor-widget-text-editor\" data-id=\"19eb5e9\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>Thanks to the versatile language support offered by gRPC and other related open source projects, the backend can be developed in many different languages. This increases the overall flexibility and allows you to pick the right technology for your project. You might depend on existing code or start over with a modern and memory-safe language.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-ac059ec elementor-widget elementor-widget-text-editor\" data-id=\"ac059ec\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"text-editor.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t\t\t<p>In our demo, we focused on the essential components and steps required to setup a minimal connection between app and server. In real projects, the interfaces will, of course, be more complex than simple request-response communication. But on top of that gRPC also supports client-, server- and bi-directional streaming (see <a class=\"external-link\" href=\"https:\/\/grpc.io\/docs\/what-is-grpc\/core-concepts\/\" rel=\"nofollow noopener\" target=\"_blank\">gRPC core concepts<\/a>) which should cover also more complex scenarios. Thanks to Dart&#8217;s excellent support for asynchronous programming with Streams, you can use these techniques seamlessly in your Flutter app.<\/p>\t\t\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>","protected":false},"excerpt":{"rendered":"<p>In this article, we explain how to set up secure network-based communication using Flutter and gRPC. We present practical implementation steps in a hands-on example.<\/p>","protected":false},"author":18,"featured_media":4020,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1,2,803,802],"tags":[223],"class_list":["post-11647","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-allgemein","category-blog","category-flutter","category-newsletter-2025-01","tag-flutter"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts\/11647","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/users\/18"}],"replies":[{"embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/comments?post=11647"}],"version-history":[{"count":20,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts\/11647\/revisions"}],"predecessor-version":[{"id":11682,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/posts\/11647\/revisions\/11682"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/media\/4020"}],"wp:attachment":[{"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/media?parent=11647"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/categories?post=11647"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.basyskom.de\/en\/wp-json\/wp\/v2\/tags?post=11647"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}