日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gRPC四种模式、认证和授权实战演示

發(fā)布時間:2023/12/4 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gRPC四种模式、认证和授权实战演示 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

上一篇對gRPC進行簡單介紹,并通過示例體驗了一下開發(fā)過程。接下來說說實際開發(fā)常用功能,如:gRPC的四種模式、gRPC集成JWT做認證和授權(quán)等。

正文

1. gRPC四種模式服務(wù)

以下案例演示,服務(wù)端用微軟提供的模板創(chuàng)建,客戶端使用Winform程序演示,基于.NetCore3.1版本。具體創(chuàng)建步驟在上一篇說的很細了(gRPC趁現(xiàn)在還沒大火,搶先了解一下),接下來就直接搞重點;這里就模仿一個學(xué)生服務(wù),包含增、刪、改、查方法,下面是用到的proto文件的全部內(nèi)容,后續(xù)的實例就單獨標(biāo)出重點即可。

syntax?=?"proto3";?//指定版本 //?定義命名空間 option?csharp_namespace?=?"Grpc.Server.Demo"; //?指定包名,避免沖突 package?user; //?定義Student?的?message類型 message?Student?{string?UserName?=?1;int32?Age=2;string?addr?=?3; } //?公共返回類型 message?CommonResponse{int32?code?=1;string?msg=2; } //?添加學(xué)生時傳遞的類型 message?AddStudentRequest{Student?student=1;} //?查詢學(xué)生時傳遞的類型 message?QueryStudentRequest {string?UserName=1; } //?查詢?nèi)繉W(xué)生,沒有條件,但也需要一個空的message message?QueryAllStudentRequest { } //?上傳圖片 message?UploadImgRequest{bytes?data?=?1; } message?StudentResponse?{Student?student?=1; } message?TokenRequest{string?UserName=1;string?UserPwd=2; } message?TokenResponse{string?Token?=1; } //?約定需要提供的服務(wù)方法 service?StudentService{rpc?GetToken(TokenRequest)?returns?(TokenResponse);//?簡單模式,查詢rpc?GetStudentByUserName(QueryStudentRequest)?returns?(StudentResponse);//?服務(wù)端流模式rpc?GetAllStudent(QueryAllStudentRequest)?returns?(stream?StudentResponse);//?客戶端流模式rpc?UploadImg(stream?UploadImgRequest)?returns?(CommonResponse);//?雙向流模式rpc?AddManyStudents(stream?AddStudentRequest)?returns?(stream?StudentResponse); }

整體的項目結(jié)構(gòu)如下:

1.1 簡單模式

和現(xiàn)在http方式類似:客戶端發(fā)出單個請求,服務(wù)端返回單個響應(yīng)。

關(guān)于簡單模式,請求參數(shù)和返回參數(shù)都是一般message類型,在上一篇中演示的模式就是簡單模式,歸納如下步驟;

服務(wù)端

  • 增加一個student.proto文件,在文件中定義服務(wù),編譯自動生成對應(yīng)代碼

    定義服務(wù)格式:

    rpc 方法名(請求類型) returns (返回類型);

  • 新建StudentDemoService類,繼承生成的代碼類,開始寫業(yè)務(wù)

  • 在Startup文件中將服務(wù)方法暴露出去(這里寫一次即可,后續(xù)就不重復(fù)說了)

    到這服務(wù)端就寫完啦,其實和原來寫WebApi接口一樣便捷。

客戶端

使用Winform的形式舉例演示客戶端,在創(chuàng)建項目時,直接選擇Winform模板即可,簡單設(shè)計了一下界面,如下:

  • 引入對應(yīng)的包,將服務(wù)端的proto文件都拷過來(服務(wù)端和客戶端proto文件一致)

    如果編譯沒自動生成代碼,需要檢查是否引入對應(yīng)的包,是否設(shè)置了student.proto文件的屬性,如果這塊還不了解,點這里(gRPC趁現(xiàn)在還沒大火,搶先了解一下)先熟悉以下開發(fā)過程。

  • 在winform設(shè)計模式下,雙擊按鈕增加點擊事件,開始寫業(yè)務(wù)邏輯

  • 運行看效果

    先運行服務(wù)端,在運行客戶端,輸入條件,點擊簡單模式按鈕,效果如下:

    這里查不到數(shù)據(jù),客戶端程序報異常(別罵我代碼寫的不嚴謹,小伙伴處理一下就好啦)

1.2 服務(wù)端流模式

客戶端發(fā)起一個請求到服務(wù)端,服務(wù)端返回連續(xù)的數(shù)據(jù)流;一般用在服務(wù)端分批返回數(shù)據(jù)的情況,客戶端能持續(xù)接收服務(wù)端的數(shù)據(jù)。

服務(wù)端

  • 在student.proto文件中增加服務(wù),編譯自動生成代碼

    定義服務(wù)格式:

    rpc 方法名(請求類型) returns (stream 返回類型);

  • 在StudentDemoService類中,重寫方法寫業(yè)務(wù)邏輯代碼

    注意點:

  • 就算請求不需要參數(shù),也需要一個空的message類型;

  • 這里返回的數(shù)據(jù)可以分批發(fā)送,復(fù)用連接,提高效率;

  • 客戶端

    • student.proto文件保證和服務(wù)端一樣同步添加相應(yīng)的內(nèi)容

      這里就不截圖了,小伙伴可以通過拷貝或是引用的方式保證文件一樣就行啦

    • 在winform設(shè)計模式下,雙擊服務(wù)端流模式按鈕增加點擊事件,開始寫業(yè)務(wù)邏輯

    • 運行看效果

      先運行服務(wù)端,在運行客戶端,點擊服務(wù)端流模式按鈕,效果如下:

    1.3 客戶端流模式

    客戶端將連續(xù)的數(shù)據(jù)流發(fā)送到服務(wù)端,服務(wù)端返回一個響應(yīng);用在客戶端發(fā)送多次請求到服務(wù)端情況,如分段上傳圖片場景等。

    服務(wù)端

    • 在student.proto文件中增加服務(wù),編譯自動生成代碼

      定義服務(wù)格式:

      rpc 方法名(stream 請求類型) returns (返回類型);

    • 在StudentDemoService類中,重寫方法寫業(yè)務(wù)邏輯代碼

    客戶端

    • student.proto文件保證和服務(wù)端一樣同步添加相應(yīng)的內(nèi)容

      這里就不截圖了,小伙伴可以通過拷貝或是引用的方式保證文件一樣就行啦。

    • 在winform設(shè)計模式下,雙擊客戶端流模式按鈕增加點擊事件,開始寫業(yè)務(wù)邏輯。代碼稍多,不截圖了,不然圖片大要失真,直接上代碼吧。

      private?async?void?btn_client_Click(object?sender,?EventArgs?e) {//?用于存放選擇的文件路徑string?filePath?=?string.Empty;//?打開文件選擇對話框if?(this.openFileDialog1.ShowDialog()?==?DialogResult.OK){filePath?=?this.openFileDialog1.FileName;}if(string.IsNullOrEmpty(filePath)){this.txt_result.Text?=?"請選擇文件";return;}//1、創(chuàng)建grpc客戶端using?var?channel?=?GrpcChannel.ForAddress("https://localhost:5001");var?grpcClient?=?new?StudentService.StudentServiceClient(channel);//2、讀取選擇的文件FileStream?fileStream?=?File.OpenRead(filePath);//3、通過客戶端請求流將文件流發(fā)送的服務(wù)端using?var?call?=?grpcClient.UploadImg();var?clientStream?=?call.RequestStream;//4、循環(huán)發(fā)送,指定發(fā)送完文件while(true){//?一次最多發(fā)送1024字節(jié)byte[]?buffer?=?new?byte[1024];int?nRead?=?await?fileStream.ReadAsync(buffer,?0,?buffer.Length);//?直到讀不到數(shù)據(jù)為止,即文件已經(jīng)發(fā)送完成,即退出發(fā)送if(nRead==0){break;}//?5、將每次讀取到的文件流通過客戶端流發(fā)送到服務(wù)端await?clientStream.WriteAsync(new?UploadImgRequest?{?Data?=?ByteString.CopyFrom(buffer)?});}//?6、發(fā)送完成之后,告訴服務(wù)端發(fā)送完成await?clientStream.CompleteAsync();//?7、接收返回結(jié)果,并顯示在文本框中var?res?=?await?call.ResponseAsync;this.txt_result.Text?=?$"上傳返回Code:{res.Code},Msg:{res.Msg}"; }
    • 運行看效果

      先運行服務(wù)端,在運行客戶端,點擊客戶端流模式按鈕,效果如下:

      在彈框中選擇一個jpg的圖片(因為方便演示,服務(wù)端固定寫為jpg了),如下:

      選擇完圖片就開始上傳了,如下:

      是不是已經(jīng)感覺到gRPC的優(yōu)點了,數(shù)據(jù)傳輸量及方式有沒有先進一點。

    1.4 雙向流模式

    雙向流就是服務(wù)端流和客戶端流的整合,請求和返回都可以通過流的方式交互。

    服務(wù)端

    • 在student.proto文件中增加服務(wù),編譯自動生成代碼

      定義服務(wù)格式:

      rpc 方法名(stream 請求類型) returns (stream 返回類型);

    • 在StudentDemoService類中,重寫方法寫業(yè)務(wù)邏輯代碼

    客戶端

    • student.proto文件保證和服務(wù)端一樣同步添加相應(yīng)的內(nèi)容

      這里就不截圖了,小伙伴可以通過拷貝或是引用的方式保證文件一樣就行啦

    • 在winform設(shè)計模式下,雙擊雙向流模式按鈕增加點擊事件,開始寫業(yè)務(wù)邏輯。

    • 運行看效果

      先運行服務(wù)端,在運行客戶端,點擊雙向流模式按鈕,效果如下:

      點擊服務(wù)端流按鈕查看全部數(shù),看看是否添加成功:

    gRPC的四種模式就簡單介紹這么多,小伙伴可以根據(jù)提供的思路應(yīng)用到項目中。在演示案例中是不是感受到gRPC相比WebApi有更多的選擇和優(yōu)勢,另外通過服務(wù)端的控制臺可以看到,交互使用的是HTTP/2協(xié)議,小伙伴感興趣可以去了解一下:

    2. gRPC集成JWT認證

    和WebAPI一樣,如果提供的服務(wù)接口“裸奔”,那么風(fēng)險是很大的;關(guān)于這點,之前針對WebApi認證和授權(quán)分享了兩篇文章,傳送門在這(跟我一起學(xué).NetCore之WebApi接口裸奔有風(fēng)險(Jwt)、跟我一起學(xué).NetCore之熟悉的接口權(quán)限驗證不能少(Jwt))。

    其實gRPC集成JWT做認證授權(quán),和原來WebApi集成方式差不多一樣,太細節(jié)的描述小伙伴可以查閱上面兩篇文章;接下來的需求目的就是把上面提供的服務(wù)保護起來,只有認證通過才能調(diào)用。

    2.1 引入Jwt相關(guān)包,注冊服務(wù),中間件管道增加認證流程
    • 在gRPC服務(wù)端項目中引入Jwt相關(guān)包

      Microsoft.AspNetCore.Authentication.JwtBearer

    • 在Startup文件中注冊相關(guān)服務(wù)

    • 在Startup文件中增加認證流程

    • 在服務(wù)上增加Authorize特性標(biāo)識

      運行看效果:

      通過調(diào)用結(jié)果得知,現(xiàn)在提供的gRPC服務(wù)已經(jīng)受到保護,需要持有對應(yīng)身份的請求才能訪問,所以接下來就需要服務(wù)端提供一個獲取身份Token的方法。

    2.2 服務(wù)端增加獲取Token的服務(wù)方法
    • 服務(wù)端增加獲取Token的服務(wù)方法

      現(xiàn)在student.proto文件中增加獲取Token的相關(guān)約定,編譯自動生成對應(yīng)代碼,如下:

      重寫方法,編寫獲取Token的邏輯,如下:

      生成token的核心邏輯為方法GenerateToken,如下:

      到這,服務(wù)端生成Token的方法就搞定了,接下開始讓客戶端獲取并使用即可。

    2.3 客戶端獲取Token并使用
    • 確保student.proto文件內(nèi)容和服務(wù)端的一致,然后編譯自動生成代碼。

      這里就不截圖了,小伙伴可以通過拷貝或是引用的方式保證文件一樣就行啦

    • 這里將服務(wù)端流模式的按鈕復(fù)制一個出來,在其點擊事件中增加帶Token的邏輯

      獲取Token的邏輯就是簡單的調(diào)用服務(wù)端的方法,如下:

      這樣就完成Jwt的集成了,服務(wù)端、客戶端都運行起來看一下:

    到這里,gRPC集成Jwt做認證的全部演示就完成了,除了調(diào)用方式和客戶端傳遞Token的方式不一樣,其他的都和WebApi使用方式一樣。

    重點:這里gRPC可以通過Metadata進行傳遞數(shù)據(jù),和之前WebApi的請求頭很像,可以根據(jù)自己需求進行任意封裝傳遞。

    3. gRPC權(quán)限驗證思路提一下

    上面只是進行了認證,還沒有對服務(wù)方法權(quán)限進行管控,只要認證通過就能調(diào)用全部服務(wù)方法;在實際應(yīng)用場景中更希望的是分配啥權(quán)限才能調(diào)用對應(yīng)的服務(wù),所以權(quán)限管控少不了。

    gRPC的權(quán)限管控和WebApi的管控方式一樣,同樣可以使用策略的方式進行權(quán)限驗證。gRPC同樣能獲取到請求方法的Url(包名.服務(wù)名.方法名),這樣就可以以這種規(guī)則進行權(quán)限配置,然后驗證即可。詳細步驟可以參考跟我一起學(xué).NetCore之熟悉的接口權(quán)限驗證不能少(Jwt),接下來就來說說主要步驟:

    3.1 使用動態(tài)權(quán)限策略形式
    • 增加一個PermissionRequirement.cs文件,如下:

    • 增加一個PermissionHandler.cs文件,集成自AuthorizationHandler,然后重寫處理方法,核心代碼如下:

    • Startup.cs文件中注冊相關(guān)服務(wù),如下:

    • 在Authorize特性中傳遞對應(yīng)的策略名稱,如下:

    • 這里模擬配置權(quán)限,在獲取token方法中內(nèi)置幾條對應(yīng)用戶的權(quán)限數(shù)據(jù)

    • 運行看效果,如下:

      最后驗證成功就正常返回結(jié)果,如果驗證不成功就返回失敗,客戶端就報異常,如下:

    源代碼地址:https://gitee.com/CodeZoe/g-rpc/tree/master

    后續(xù)會把其他代碼也整理到碼云上。

    總結(jié)

    關(guān)于gRPC實際應(yīng)用場景常用的功能就先說到這吧,以上案例演示只是提供思路,小伙伴使用時可以根據(jù)對應(yīng)的需求進行擴展和處理。

    既然聊到了服務(wù)間通信,分布式事務(wù)肯定是避不開的,下一篇開始說說分布式事務(wù)相關(guān)的點。

    一個被程序搞丑的帥小伙,關(guān)注"Code綜藝圈",和我一起學(xué)~~~

    總結(jié)

    以上是生活随笔為你收集整理的gRPC四种模式、认证和授权实战演示的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。