2017上海國際汽車新能源及智慧技術展覽會

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

聚甘新

特斯拉財報翻紅,帶動電池材料業興盛

美國電動車商特斯拉(Tesla)於10月26日發表今年第三季財報,以淨營收2,190萬美元的成果翻紅,EPS相當於每股0.14美元。全球電動車市場蓬勃,且Model 3車款的訂單爆量,市況前景佳,也帶動了上游的供應鏈興盛。為特斯拉車用電池供應原料的日本住友金屬礦山(Sumitomo Metal Mining)也宣布將擴大產能。

特斯拉轉盈

特斯拉今年第三季的淨營收為2,190萬美元,EPS每股0.14美元,較去年每股虧損1.78美元有大幅成長。經會計調整後,第三季EPS為0.71美元,遠高於原先路透社調查預估的虧損0.54美元。會計調整後營收23億美元,也優於原先法人預期的19.8億美元。

特斯拉執行長Elon Musk在財報說明會上表示,今年下半年仍力求出貨5萬輛電動車的目標,並將致力於提升毛利率;在此基礎下,Musk看好第四季營收仍將持續獲利。

特斯拉亦指出,Model 3的交車時間表仍在軌道上,相當於駁斥Model 3將會面臨交車延遲的市場傳聞。特斯拉第三季財報的表現,也將影響股東於11月17日的股東會上針對是否併購SolarCity之投票案的意願。

特斯拉訂單多,上游樂

特斯拉的車用電池由Panasonic提供,而Panasonic的鋰離子電池其中一項原料──鎳酸鋰,則幾乎都由日本住友金屬礦山供應。因應特斯拉訂單強勁,以及全球電動車需求成長,住友金屬礦山宣布砸下180億日圓資金,擴大鎳酸鋰產能。

住友金屬礦山目前的鎳酸鋰每月產能約為1,850噸,預計在2018年1月擴產至3,550噸,以供應未來電動車用鋰電池所需。同時,住友金屬礦山也與Panasonic合作研發高性能鎳酸鋰的產能。

住友金屬礦山的擴產計畫,與特斯拉預計在2017年開始出貨Model 3有直接關聯。加上特斯拉預計2018年要出貨50萬輛Model 3,住友金屬礦山也因此將原先擴產到2,550噸的計畫提高到3,550噸。

其他鋰電池材料,如正負極、分隔膜、電解液等,日系、韓系廠商如住友化學、Toray、旭化成、昭和電工等的市占率相當高。這些廠商也都看好電動車市場的需求繼續成長,持續有擴產計畫,並與鋰電池大廠Panasonic、LG Chem等公司密切合作。

(照片來源: shared by CC 2.0)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司“嚨底家”!

※推薦評價好的iphone維修中心

聚甘新

台電動車廠凱勝新廠動土,打造綠能產業聚落

台灣本地的電動車大廠凱勝綠能科技正式於嘉義縣馬稠後工業區破土興建新廠房。馬稠後廠房共分三廠,總投資額達新台幣60億元,首期一廠工程預計在2018年完工,將成為台灣規模最大的電動車生產基地,並將進一步投入綠能相關產業的研發製造。

凱勝綠能的招牌產品為電動巴士,是目前台灣最大的電動巴士生產商。為深耕台灣在地電動車產業,凱勝綠能看上馬稠後工業區的地理區位,規劃興建三個廠房。投資新台幣25億元的一廠工程於11月1日正式動土,預計在2018年完工,屆時電動巴士產能可提高到1,000餘輛,年產值新台幣300億元以上,並可創造當地就業和10億餘元的地方稅收。

凱勝綠能董事長陳怡仁表示,馬稠後工廠一廠除將進行電動車研發生產外,更將投入太陽能綠電與儲能系統的開發和應用,如提升電池儲能功能等。到了二、三廠陸續完工後,還將投入各式電動載具與相關產品的研發製造,屆時馬稠後工廠不僅會是全台規模最大的電動車建案,也將形成完整的電動車與綠能產業研發基地。

陳怡仁指出,電動車是「零排放、零汙染、零噪音」的「三零」產業,將有助守護台灣與地球環境。嘉義縣長張花冠亦蒞臨破土典禮,並親自試乘凱勝綠能的電動車。

(照片:嘉義縣長張花冠試乘電動車。來源:嘉義縣政府)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

聚甘新

EV/PHV需求夯!日本馬達零件商久野傳擴產50倍

日經新聞3日報導,日本汽車零組件商久野金屬工業(Kuno Kinzoku Industry)計畫將使用於電動車(EV)、插電式油電混合車(PHV)的馬達相關零件「馬達殼(motor housing、見附圖)」產能提高至現行的約50倍水準,主因全球各地對環保規範日益嚴苛,帶動EV/PHV今後料急速普及。馬達殼為圓筒狀的鐵製外殼,用於覆蓋住作為EV動力的大型馬達、並使其固定。

報導指出,久野位於日本常滑市的本社工廠內目前僅擁有一座生產馬達殼的設備、且最近已處於產能全開狀態,因此久野計畫投資約4億日圓、擴增設備,將月產能從現行的7,000-8,000個最高擴增至40萬個的規模。久野社長久野忠博表示,「來自顧客端的尋單持續增加」。

久野設立於1947年,於2010年左右開始供應大型馬達殼給汽車大廠使用,目前在馬達殼市場上握有高市佔率。

根據日本市調機構富士經濟(Fuji Keizai)公布的調查報告顯示,PHV、EV在2025年以後的需求增幅將加快,預估2030年左右時,油電混合車(HV)、PHV、EV將呈現幾乎相互抗衡的局面,2035年在北美、歐洲、中國需求加持下,PHV、EV市場將進一步擴大,超越HV。

富士經濟指出,全球EV市場當前將持續呈現緩和增長,不過預估自2020年左右起,EV需求將呈現急速擴大,預估2035年全球EV市場規模將達567萬台、將較2015年飆增近16倍(成長1,567%);另外,2035年全球PHV市場規模將達665萬台、將較2015年(21萬台)飆增近31倍(成長3,066%)。

(本文內容由 授權轉載)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

聚甘新

Toyota加入純電動車戰場,日產Leaf仍佔銷售鰲頭

日系車商豐田(Toyota)看好純電動車(EV)的市場,正在計畫跨入此一領域,拓展油電混和車、燃料電池車(FCV)之外的新市場,並與BMW、Tesla等國際知名車廠一較高下,並挑戰日廠Leaf的龍頭地位。

《日經》中文網報導,Toyota預計最快在2017年新設EV的開發與設計部門,並整合集團資源,盡快投入量產。Toyota將整合油電混和車Prius和經典車款Corolla的平台技術,以推出一次充電續航力300公尺的純電動車為首要目標。此外,由於SUV車款頗受歡迎,Toyota也會考慮推出純電動車版的SUV車款。

同時,Toyota將加速今年1月成立的電池材料技術部門的研發進度,也會考慮向外採購核心零組件,以強化電動車用電池的性能。

市場競爭者多,日產Leaf仍占銷售龍頭

Toyota曾於2012~2014年間在美國與Tesla共同開發過SUV純電動車,但考量到電池的成本與性能限制等問題,並未積極發展純電動車事業。然而,隨著Tesla、BMW、Volkswagen、BYD等國際大廠加入戰局,電動車的各項零件性能與續航力都有顯著的提升,也使Toyota決定重新加入開發純電動車的行列。

MoneyDJ引述日媒Sankei Biz的報導表示,截至2016年8月為止,日產Leaf仍然是全球最暢銷的電動車,累計銷售量達23.4萬輛。不過,Leaf正與Tesla展開激烈的銷售戰。

報導指出,日本市調機構富士經濟預測,插電式油電混和車(PHEV)和純電動車的需求在2025年以後將會加速,2030年時將能與油電混和車廂庭抗禮;2035年時,PHEV和電動車的市場將超越油電混和車。屆時全球電動車的市場規模將達567萬輛,較2015年成長16倍之多。

(照片來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

聚甘新

Chevrolet Bolt平價電動車投產、續航力近400公里

美聯社5日報導,通用汽車(General Motors)已開始在美國密西根州奧萊恩(Orion)鎮生產Chevrolet Bolt。這台續航力達238英里(383公里)的電動車建議零售價37,495美元起(註:最多可取得7,500美元的聯邦折抵稅額、扣除後入手價相當於29,995美元),今年底以前將於加州、奧勒岡州開賣,明年將擴及全美其他地區。根據凱利藍皮書(Kelley Blue Book)的統計,美國新車平均價格為34,000美元。特斯拉(Tesla Motors Inc.)200英里續航力、35,000美元(註:扣除聯邦折抵稅額前)Model 3電動車預計自2017年下半年開始交車。

IHS Markit汽車業分析師Stephanie Brinley指出,Bolt續航力遠高於美國平均來回通勤距離(40英里),但有時人們回家後可能忘了或沒有足夠時間進行充電,這是電動車主得多加費心的地方。美國目前使用中的電動車數量約23.5萬台,IHS預估Bolt開賣第一年銷售量逼近3萬台。美國去年電動車銷售量為10萬台,IHS預估年度銷售量將在2020年升至30萬台、2025年挑戰40萬台。

華爾街日報報導,通用汽車2015年10月宣布與LG電子結盟、後者將成為Chevrolet Bolt電動車的主要關鍵零件供應商。

英國金融時報8月報導,國際能源署(IEA)首席經濟學家Laszlo Varro指出,電動車目前對商品(原油)市場的影響力大約就像是10年前的太陽能一樣。他說,太陽能現在已是一個規模達數百億美元的市場、擁有龐大的影響力。Varro提到,電動車需達5千萬至1億台的規模、才能取代相當於100萬桶的石油日消費量。

IEA數據顯示,2009年全球40個國家合計僅有不到6千台的電動車、去年已升至120萬台。麥格理集團全球能源策略師Vikas Dwivedi指出,沙烏地阿拉伯對電動車的長期發展存有戒心,這可能就是它為何宣布將讓沙烏地阿拉伯國家石油公司(Saudi Aramco)初次公開發行(IPO)的原因之一。

CNNMoney去年底報導,石油輸出國組織(OPEC)發表的年度「世界石油展望(World Oil Outlook)」報告顯示,2040年高達94%的使用中車輛仍將是依靠石油燃料。OPEC報告顯示,除非出現重大技術性突破,否則在可預見的未來電動車將難以大幅取得市佔率。油國組織預估2040年僅有1%的車輛銷售量是來自純電動車款。

能源情報署(EIA)公布,截至2016年10月28日為止當週美國商用汽油庫存報2.238億桶、較去年同期高出3.9%。EIA公布的數據顯示,美國一般汽油每加侖零售均價10月31日報2.230美元,較一年前高出0.006美元。

(照片來源:。本文內容由 授權提供)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※想知道最厲害的網頁設計公司“嚨底家”!

※別再煩惱如何寫文案,掌握八大原則!

※產品缺大量曝光嗎?你需要的是一流包裝設計!

聚甘新

台北萬豪酒店首設Tesla充電站,即日啟用

美商特斯拉(Tesla)於今年9月正式進軍台灣,在台引發電動車熱。台北萬豪酒店宣布與Tesla合作設置充電站,同時推出限時活動,鼓勵民眾響應環保行動。

繼在台灣科技大學校區內設置充電站後,Tesla正式宣布與台北萬豪酒店合作,於飯店內設置6組充電站,成為全台首家提供Tesla電動車充電服務的飯店。車主只要於飯店內消費,就可免費享有充電服務。

台北萬豪酒店主管表示,萬豪國際的核心理念是「擁抱改變」,不但要跟著時代進步,還要勇於創新,與Tesla的形象相輔相成。藉由與Tesla合作設置電動車充電站,希望能提供客戶更便捷的服務,並推動現代科技。

萬豪酒店同時也推出相關活動,凡是11月30日前佩戴紅色配件到萬豪酒店消費的顧客,就可享有9折優惠。

Tesla主管表示,Tesla進入台灣市場後,將提供銷售、服務、充電等全方位服務,未來將繼續加速布建「目的地充電站」的腳步,以為台灣的Tesla車主提供更綿密的充電網絡。

除了萬豪酒店之外,台北晶華酒店也與BMW合作設置了i公共充電站,可供i3、i8等車款使用。

(照片來源:)

本站聲明:網站內容來源於EnergyTrend https://www.energytrend.com.tw/ev/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※別再煩惱如何寫文案,掌握八大原則!

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※超省錢租車方案

※教你寫出一流的銷售文案?

網頁設計最專業,超強功能平台可客製化

聚甘新

小師妹學JVM之:JIT中的LogCompilation

目錄

  • 簡介
  • LogCompilation簡介
  • LogCompilation的使用
  • 解析LogCompilation文件
  • 總結

簡介

我們知道在JVM中為了加快編譯速度,引入了JIT即時編譯的功能。那麼JIT什麼時候開始編譯的,又是怎麼編譯的,作為一個高傲的程序員,有沒有辦法去探究JIT編譯的秘密呢?答案是有的,今天和小師妹一起帶大家來看一看這個編譯背後的秘密。

更多精彩內容且看:

  • 區塊鏈從入門到放棄系列教程-涵蓋密碼學,超級賬本,以太坊,Libra,比特幣等持續更新
  • Spring Boot 2.X系列教程:七天從無到有掌握Spring Boot-持續更新
  • Spring 5.X系列教程:滿足你對Spring5的一切想象-持續更新
  • java程序員從小工到專家成神之路(2020版)-持續更新中,附詳細文章教程

LogCompilation簡介

小師妹:F師兄,JIT這麼神器,但是好像就是一個黑盒子,有沒有辦法可以探尋到其內部的本質呢?

追求真理和探索精神是我們作為程序員的最大優點,想想如果沒有玻爾關於原子結構的新理論,怎麼會有原子體系的突破,如果沒有海森堡的矩陣力學,怎麼會有量子力學的建立?

JIT的編譯日誌輸出很簡單,使用 -XX:+LogCompilation就夠了。

如果要把日誌重定向到一個日誌文件中,則可以使用-XX:LogFile= 。

但是要開啟這些分析的功能,又需要使用-XX:+UnlockDiagnosticVMOptions。 所以總結一下,我們需要這樣使用:

-XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -XX:LogFile=www.flydean.com.log

LogCompilation的使用

根據上面的介紹,我們現場來生成一個JIT的編譯日誌,為了體現出專業性,這裏我們需要使用到JMH來做性能測試。

JMH的全稱是Java Microbenchmark Harness,是一個open JDK中用來做性能測試的套件。該套件已經被包含在了JDK 12中。

如果你使用的不是JDK 12,那麼需要添加如下依賴:

<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-core</artifactId>
    <version>1.19</version>
</dependency>
<dependency>
    <groupId>org.openjdk.jmh</groupId>
    <artifactId>jmh-generator-annprocess</artifactId>
    <version>1.19</version>
</dependency>

更多詳情可以參考我之前寫的: 在java中使用JMH(Java Microbenchmark Harness)做性能測試一文。

之前有的朋友說,代碼也用圖片,看起來好看,從本文之後,我們會盡量把代碼也轉成圖片來展示:

看完我的JMH的介紹,上面的例子應該很清楚了,主要就是做一個累加操作,然後warmup 5輪,測試5輪。

在@Fork註解裏面,我們可以配置jvm的參數,為什麼我註釋掉了呢?因為我發現在jvmArgsPrepend中的-XX:LogFile是不生效的。

沒辦法,我只好在運行配置中添加:

運行之後,你就可以得到輸出的編譯日誌文件。

解析LogCompilation文件

小師妹:F師兄,我看了一下生成的文件好複雜啊,用肉眼能看得明白嗎?

別怕,只是內容的多一點,如果我們細細再細細的分析一下,你會發現其實它真的非常非常……複雜!

其實寫點簡單的小白文不好嗎?為什麼要來分析這麼複雜,又沒人看,看了也沒人懂的JVM底層…..

大概,這就是專業吧!

LogCompilation文件其實是xml格式的,我們現在來大概分析一下,它的結構,讓大家下次看到這個文件也能夠大概了解它的重點。

首先最基本的信息就是JVM的信息,包括JVM的版本,JVM運行的參數,還有一些properties屬性。

我們收集到的日誌其實是分兩類的,第一類是應用程序本身的的編譯日誌,第二類就是編譯線程自己內部產生的日誌。

第二類的日誌會以hs_c*.log的格式存儲,然後在JVM退出的時候,再將這些文件跟最終的日誌輸出文件合併,生成一個整體的日誌文件。

比如下面的兩個就是編譯線程內部的日誌:

<thread_logfile thread='22275' filename='/var/folders/n5/217y_bgn49z18zvjch907xb00000gp/T//hs_c22275_pid83940.log'/>
<thread_logfile thread='41731' filename='/var/folders/n5/217y_bgn49z18zvjch907xb00000gp/T//hs_c41731_pid83940.log'/>

上面列出了編譯線程的id=22275,如果我們順着22275找下去,則可以找到具體編譯線程的日誌:

<compilation_log thread='22275'>
...
</compilation_log>

上面由compilation_log圍起來的部分就是編譯日誌了。

接下來的部分表示,編譯線程開始執行了,其中stamp表示的是啟動時間,下圖列出了一個完整的編譯線程的日誌:

<start_compile_thread name='C2 CompilerThread0' thread='22275' process='83940' stamp='0.058'/>

接下來描述的是要編譯的方法信息:

<task compile_id='10' method='java.lang.Object <init> ()V' bytes='1' count='1409' iicount='1409' stamp='0.153'>

上面列出了要編譯的方法名,compile_id表示的是系統內部分配的編譯id,bytes是方法中的字節數,count表示的是該方法的調用次數,注意,這裏的次數並不是方法的真實調用次數,只能做一個估計。

iicount是解釋器被調用的次數。

task執行了,自然就會執行完成,執行完成的內容是以task_done標籤來表示的:

<task_done success='1' nmsize='120' count='1468' stamp='0.155'/>

其中success表示是否成功執行,nmsize表示編譯器編譯出來的指令大小,以byte為單位。如果有內聯的話,還有個inlined_bytes屬性,表示inlined的字節個數。

<type id='1025' name='void'/>

type表示的是方法的返回類型。

<klass id='1030' name='java.lang.Object' flags='1'/>

klass表示的是實例和數組類型。

<method id='1148' holder='1030' name='<init>' return='1025' flags='1' bytes='1' compile_id='1' compiler='c1' level='3' iicount='1419'/>

method表示執行的方法,holder是前面的klass的id,表示的是定義該方法的實例或者數組對象。method有名字,有
return,return對應的是上面的type。

flags表示的是方法的訪問權限。

接下來是parse,是分析階段的日誌:

<parse method='1148' uses='1419.000000' stamp='0.153'>

上面有parse的方法id。uses是使用次數。

<bc code='177' bci='0'/>

bc是byte Count的縮寫,code是byte的個數,bci是byte code的索引。

<dependency type='no_finalizable_subclasses' ctxk='1030'/>

dependency分析的是類的依賴關係,type表示的是什麼類型的依賴,ctkx是依賴的context class。

我們注意有的parse中,可能會有uncommon_trap:

<uncommon_trap bci='10' reason='unstable_if' action='reinterpret' debug_id='0' comment='taken never'/>

怎麼理解uncommon_trap呢?字面上意思就是捕獲非常用的代碼,就是說在解析代碼的過程中發現發現這些代碼是uncommon的,然後解析產生一個uncommon_trap,不再繼續進行了。

它裏面有兩個比較重要的字段,reason表示的是被標記為uncommon_trap的原因。action表示的出發uncommon_trap的事件。

有些地方還會有call:

<call method='1150' count='5154' prof_factor='1.000000' inline='1'/>

call的意思是,在該代碼中將會調用其他的方法。count是執行次數。

總結

複雜的編譯日誌終於講完了,可能講的並不是很全,還有一些其他情況這裏並沒有列出來,後面如果遇到了,我再添加進去。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/jvm-jit-logcompilation/

本文來源:flydean的博客

歡迎關注我的公眾號:程序那些事,更多精彩等着您!

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※為什麼 USB CONNECTOR 是電子產業重要的元件?

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

※台北網頁設計公司全省服務真心推薦

※想知道最厲害的網頁設計公司“嚨底家”!

※推薦評價好的iphone維修中心

聚甘新

.Net Core微服務入門全紀錄(五)——Ocelot-API網關(下)

前言

上一篇【.Net Core微服務入門全紀錄(四)——Ocelot-API網關(上)】已經完成了Ocelot網關的基本搭建,實現了服務入口的統一。當然,這隻是API網關的一個最基本功能,它的進階功能還有很多很多。

服務發現

首先需要解決的就是服務發現的問題,服務發現的優點之前講過,就不說了。
上一篇中我們的服務地址都是寫在ocelot.json配置文件里,現在我們需要結合之前的Consul來實現服務發現。

  • 改造代碼:

首先NuGet安裝Ocelot.Provider.Consul

修改Startup.cs:

        public void ConfigureServices(IServiceCollection services)
        {
            //添加ocelot服務
            services.AddOcelot()
                .AddConsul();//添加consul支持
        }

修改ocelot.json配置:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/products",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    },
    {
      "DownstreamPathTemplate": "/orders",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "OrderService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9070",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

這個配置應該很好理解,就是把我們上次的DownstreamHostAndPorts節點去掉了,然後增加了ServiceDiscoveryProvider服務發現相關配置。
注意,Ocelot除了支持Consul服務發現以外,還有Eureka也可以,Eureka也是一個類似的註冊中心。

好了,代碼修改就差不多了,下面運行程序測試一下:

客戶端正常運行。

至此我們就實現了服務註冊與發現和api網關的基本功能。接下來就要提到:服務治理

服務治理

其實服務治理也沒有一個非常明確的定義。它的作用簡單來說,就是幫助我們更好的管理服務,提升服務的可用性。——緩存,限流,熔斷,鏈路追蹤 等等。。。都屬於常用的服務治理手段。
之前講的負載均衡,服務發現也可以算是服務治理。

  • 緩存:

在Ocelot中啟用緩存,需要NuGet安裝一下Ocelot.Cache.CacheManager

修改Startup.cs中的ConfigureServices()方法:

//添加ocelot服務
services.AddOcelot()
    //添加consul支持
    .AddConsul()
    //添加緩存
    .AddCacheManager(x =>
    {
        x.WithDictionaryHandle();
    });

修改ocelot.json配置文件:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/products",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      }
    },
    {
      "DownstreamPathTemplate": "/orders",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "OrderService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9070",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    }
  }
}

在Routes路由配置中增加了FileCacheOptions。TtlSeconds代表緩存的過期時間,Region代表緩衝區名稱,這個我們目前用不到。

好了,代碼修改完需要編譯重啟一下網關項目,然後打開客戶端網站測試一下:

可以看到,5秒之內的請求都是同樣的緩存數據。Ocelot也支持自定義緩存。

  • 限流:

限流就是限制客戶端一定時間內的請求次數。
繼續修改配置:

{
  "Routes": [
    {
      "DownstreamPathTemplate": "/products",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/products",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "ProductService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      },
      "RateLimitOptions": {
        "ClientWhitelist": [ "SuperClient" ],
        "EnableRateLimiting": true,
        "Period": "5s",
        "PeriodTimespan": 2,
        "Limit": 1
      }
    },
    {
      "DownstreamPathTemplate": "/orders",
      "DownstreamScheme": "http",
      "UpstreamPathTemplate": "/orders",
      "UpstreamHttpMethod": [ "Get" ],
      "ServiceName": "OrderService",
      "LoadBalancerOptions": {
        "Type": "RoundRobin"
      },
      "FileCacheOptions": {
        "TtlSeconds": 5,
        "Region": "regionname"
      },
      "RateLimitOptions": {
        "ClientWhitelist": [ "SuperClient" ],
        "EnableRateLimiting": true,
        "Period": "5s",
        "PeriodTimespan": 2,
        "Limit": 2
      }
    }
  ],
  "GlobalConfiguration": {
    "BaseUrl": "http://localhost:9070",
    "ServiceDiscoveryProvider": {
      "Scheme": "http",
      "Host": "localhost",
      "Port": 8500,
      "Type": "Consul"
    },
    "RateLimitOptions": {
      "DisableRateLimitHeaders": false,
      "QuotaExceededMessage": "too many requests...",
      "HttpStatusCode": 999,
      "ClientIdHeader": "Test"
    }
  }
}

在Routes路由配置中增加了RateLimitOptions。ClientWhitelist代表客戶端白名單,在白名單中的客戶端可以不受限流的影響;EnableRateLimiting代表是否限流;Period代表限流的單位時間,例如1s,5m,1h,1d等;PeriodTimespan代表客戶端達到請求上限多少秒后可以重試;Limit代表客戶端在定義的時間內可以發出的最大請求數。
在GlobalConfiguration配置中也增加了RateLimitOptions。DisableRateLimitHeaders代表是否禁用X-Rate-Limit和Retry-After標頭(請求達到上限時response header中的限制數和多少秒后能重試);QuotaExceededMessage:代表請求達到上限時返回給客戶端的消息;HttpStatusCode:代表請求達到上限時返回給客戶端的HTTP狀態代碼。ClientIdHeader可以允許自定義用於標識客戶端的標頭。默認情況下為“ ClientId”。
最重要的就是Period,PeriodTimespan,Limit這幾個配置。

重新編譯啟動看一下效果:

  • 超時/熔斷

超時很好理解,就是網關請求服務時可容忍的最長響應時間。熔斷的意思就是當請求某個服務的異常次數達到一定量時,那麼網關在一定時間內就不再對這個服務發起請求了,直接熔斷。
Ocelot中啟用 超時/熔斷 需要NuGet安裝一下Ocelot.Provider.Polly

修改Startup.cs中的ConfigureServices()方法:

//添加ocelot服務
services.AddOcelot()
    //添加consul支持
    .AddConsul()
    //添加緩存
    .AddCacheManager(x =>
    {
        x.WithDictionaryHandle();
    })
    //添加Polly
    .AddPolly();

同樣的在ocelot.json路由配置中增加QoSOptions:

"QoSOptions": {
        "ExceptionsAllowedBeforeBreaking": 3,
        "DurationOfBreak": 10000,
        "TimeoutValue": 5000
      }

ExceptionsAllowedBeforeBreaking代表發生錯誤的次數,DurationOfBreak代表熔斷時間,TimeoutValue代表超時時間。
以上的配置意思就是當服務發生3次錯誤時,那麼就熔斷10秒,期間客戶端的請求直接返回錯誤,10秒之後恢復。
這個不太好模擬,就不演示了,應該也挺好理解的。

。。。。。。

關於服務治理的學問還有很多,不繼續了。。。就到此為止吧。
想要更深入了解Ocelot的,請看官網:https://ocelot.readthedocs.io/en/latest/
或者看源碼:https://github.com/ThreeMammals/Ocelot

下一篇準備說一下:事件總線。

代碼放在:https://github.com/xiajingren/NetCoreMicroserviceDemo

未完待續…

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

※教你寫出一流的銷售文案?

※超省錢租車方案

聚甘新

認證授權方案之JwtBearer認證

1.前言

回顧:認證方案之初步認識JWT

在現代Web應用程序中,即分為前端與後端兩大部分。當前前後端的趨勢日益劇增,前端設備(手機、平板、電腦、及其他設備)層出不窮。因此,為了方便滿足前端設備與後端進行通訊,就必須有一種統一的機制。所以導致API架構的流行。而RESTful API這個API設計思想理論也就成為目前互聯網應用程序比較歡迎的一套方式。

這種API架構思想的引入,因此,我們就需要考慮用一種標準的,通用的,無狀態的,與語言無關的身份認證方式來實現API接口的認證。

HTTP提供了一套標準的身份驗證框架:服務端可以用來針對客戶端的請求發送質詢(challenge),客戶端根據質詢提供應答身份驗證憑證。

質詢與應答的工作流程如下:服務端向客戶端返回401(Unauthorized,未授權)狀態碼,並在WWW-Authenticate頭中添加如何進行驗證的信息,其中至少包含有一種質詢方式。然後客戶端可以在請求中添加Authorization頭進行驗證,其Value為身份驗證的憑證信息。

在本文中,將要介紹的是以Jwt Bearer方式進行認證。

2.Bearer認證

本文要介紹的Bearer驗證也屬於HTTP協議標準驗證,它隨着OAuth協議而開始流行,詳細定義見: RFC 6570。

     +--------+                               +---------------+
     |        |--(A)- Authorization Request ->|   Resource    |
     |        |                               |     Owner     |
     |        |<-(B)-- Authorization Grant ---|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(C)-- Authorization Grant -->| Authorization |
     | Client |                               |     Server    |
     |        |<-(D)----- Access Token -------|               |
     |        |                               +---------------+
     |        |
     |        |                               +---------------+
     |        |--(E)----- Access Token ------>|    Resource   |
     |        |                               |     Server    |
     |        |<-(F)--- Protected Resource ---|               |
     +--------+                               +---------------+

A security token with the property that any party in possession of the token (a “bearer”) can use the token in any way that any other party in possession of it can. Using a bearer token does not require a bearer to prove possession of cryptographic key material (proof-of-possession).

因此Bearer認證的核心是Token,Bearer驗證中的憑證稱為BEARER_TOKEN,或者是access_token,它的頒發和驗證完全由我們自己的應用程序來控制,而不依賴於系統和Web服務器,Bearer驗證的標準請求方式如下:

Authorization: Bearer [BEARER_TOKEN] 

那麼使用Bearer驗證有什麼好處呢?

  • CORS: cookies + CORS 並不能跨不同的域名。而Bearer驗證在任何域名下都可以使用HTTP header頭部來傳輸用戶信息。
  • 對移動端友好: 當你在一個原生平台(iOS, Android, WindowsPhone等)時,使用Cookie驗證並不是一個好主意,因為你得和Cookie容器打交道,而使用Bearer驗證則簡單的多。
  • CSRF: 因為Bearer驗證不再依賴於cookies, 也就避免了跨站請求攻擊。
  • 標準:在Cookie認證中,用戶未登錄時,返回一個302到登錄頁面,這在非瀏覽器情況下很難處理,而Bearer驗證則返回的是標準的401 challenge

3.JWT

上面介紹的Bearer認證,其核心便是BEARER_TOKEN,那麼,如何確保Token的安全是重中之重。一種是通過HTTPS的方式,另一種是通過對Token進行加密編碼簽名,而最流行的Token編碼簽名方式便是:JSON WEB TOKEN。

Json web token (Jwt), 是為了在網絡應用環境間傳遞聲明而執行的一種基於JSON的開放標準(RFC 7519)。該token被設計為緊湊且安全的,特別適用於分佈式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便於從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用於認證,也可被加密。

JWT是由.分割的如下三部分組成:

Header.Payload.Signature

還記得之前說個的一篇認證方案之初步認識JWT嗎?沒有的,可以看看,對JWT的特點和基本原理介紹,可以進一步的了解。

學習了之前的文章后,我們可以發現使用JWT的好處在於通用性、緊湊性和可拓展性。

  • 通用性:因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
  • 緊湊性:JWT的構成非常簡單,字節佔用很小,通過 GET、POST 等放在 HTTP 的 header 中,便於傳輸。
  • 可擴展性:JWT是自我包涵的,因為有了payload部分,包含了必要的一些其他業務邏輯所必要的非敏感信息,自身存儲,不需要在服務端保存會話信息, 非常易於應用的擴展。

4.開始

1. 註冊認證服務

在這裏,我們用微軟給我們提供的JwtBearer認證方式,實現認證服務註冊 。

引入nuget包:Microsoft.AspNetCore.Authentication.JwtBearer

註冊服務,將服務添加到容器中,

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();

        var Issurer = "JWTBearer.Auth";  //發行人
        var Audience = "api.auth";       //受眾人
        var secretCredentials = "q2xiARx$4x3TKqBJ";   //密鑰

        //配置認證服務
        services.AddAuthentication(x =>
        {
            x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(o=>{
            o.TokenValidationParameters = new TokenValidationParameters
            {
                //是否驗證發行人
                ValidateIssuer = true,
                ValidIssuer = Issurer,//發行人
                //是否驗證受眾人
                ValidateAudience = true,
                ValidAudience = Audience,//受眾人
                //是否驗證密鑰
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(secretCredentials)),
                
                ValidateLifetime = true, //驗證生命周期
                RequireExpirationTime = true, //過期時間
            };
        });
    }

注意說明:

一. TokenValidationParameters的參數默認值:
1. ValidateAudience = true,  ----- 如果設置為false,則不驗證Audience受眾人
2. ValidateIssuer = true ,   ----- 如果設置為false,則不驗證Issuer發布人,但建議不建議這樣設置
3. ValidateIssuerSigningKey = false,
4. ValidateLifetime = true,  ----- 是否驗證Token有效期,使用當前時間與Token的Claims中的NotBefore和Expires對比
5. RequireExpirationTime = true, ----- 是否要求Token的Claims中必須包含Expires
6. ClockSkew = TimeSpan.FromSeconds(300), ----- 允許服務器時間偏移量300秒,即我們配置的過期時間加上這個允許偏移的時間值,才是真正過期的時間(過期時間 +偏移值)你也可以設置為0,ClockSkew = TimeSpan.Zero

調用方法,配置Http請求管道:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();
        //1.先開啟認證
        app.UseAuthentication();
        //2.再開啟授權
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }

JwtBearerOptions的配置中,通常IssuerSigningKey(簽名秘鑰), ValidIssuer(Token頒發機構), ValidAudience(頒發給誰) 三個參數是必須的,后兩者用於與TokenClaims中的IssuerAudience進行對比,不一致則驗證失敗。

2.接口資源保護

創建一個需要授權保護的資源控制器,這裏我們用建立API生成項目自帶的控制器,WeatherForecastController.cs, 在控制器上使用Authorize即可

[ApiController]
[Route("[controller]")]
[Authorize]
public class WeatherForecastController : ControllerBase
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

    private readonly ILogger<WeatherForecastController> _logger;

    public WeatherForecastController(ILogger<WeatherForecastController> logger)
    {
        _logger = logger;
    }

    [HttpGet]
    public IEnumerable<WeatherForecast> Get()
    {
        var rng = new Random();
        return Enumerable.Range(1, 5).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = Summaries[rng.Next(Summaries.Length)]
        })
        .ToArray();
    }
}

3. 生成Token

因為微軟為我們內置了JwtBearer驗證,但是沒有提供Token的發放,所以這裏我們要實現生成Token的方法

引入Nugets包:System.IdentityModel.Tokens.Jwt

這裏我們根據IdentityModel.Tokens.Jwt文檔給我們提供的幫助類,提供了方法WriteToken創建Token,根據參數SecurityToken,可以實例化,JwtSecurityToken,指定可選參數的類。

        /// <summary>
        /// Initializes a new instance of the <see cref="JwtSecurityToken"/> class specifying optional parameters.
        /// </summary>
        /// <param name="issuer">If this value is not null, a { iss, 'issuer' } claim will be added, overwriting any 'iss' claim in 'claims' if present.</param>
        /// <param name="audience">If this value is not null, a { aud, 'audience' } claim will be added, appending to any 'aud' claims in 'claims' if present.</param>
        /// <param name="claims">If this value is not null then for each <see cref="Claim"/> a { 'Claim.Type', 'Claim.Value' } is added. If duplicate claims are found then a { 'Claim.Type', List&lt;object&gt; } will be created to contain the duplicate values.</param>
        /// <param name="expires">If expires.HasValue a { exp, 'value' } claim is added, overwriting any 'exp' claim in 'claims' if present.</param>
        /// <param name="notBefore">If notbefore.HasValue a { nbf, 'value' } claim is added, overwriting any 'nbf' claim in 'claims' if present.</param>
        /// <param name="signingCredentials">The <see cref="SigningCredentials"/> that will be used to sign the <see cref="JwtSecurityToken"/>. See <see cref="JwtHeader(SigningCredentials)"/> for details pertaining to the Header Parameter(s).</param>
        /// <exception cref="ArgumentException">If 'expires' &lt;= 'notbefore'.</exception>
        public JwtSecurityToken(string issuer = null, string audience = null, IEnumerable<Claim> claims = null, DateTime? notBefore = null, DateTime? expires = null, SigningCredentials signingCredentials = null)
        {
            if (expires.HasValue && notBefore.HasValue)
            {
                if (notBefore >= expires)
                    throw LogHelper.LogExceptionMessage(new ArgumentException(LogHelper.FormatInvariant(LogMessages.IDX12401, expires.Value, notBefore.Value)));
            }

            Payload = new JwtPayload(issuer, audience, claims, notBefore, expires);
            Header = new JwtHeader(signingCredentials);
            RawSignature = string.Empty;
        }

這樣,我們可以根據參數指定內容:

1. string iss = "JWTBearer.Auth";  // 定義發行人
2. string aud = "api.auth";       //定義受眾人audience
3. IEnumerable<Claim> claims = new Claim[]
{
new Claim(JwtClaimTypes.Id,"1"),
new Claim(JwtClaimTypes.Name,"i3yuan"),
};//定義許多種的聲明Claim,信息存儲部分,Claims的實體一般包含用戶和一些元數據
4. var nbf = DateTime.UtcNow;  //notBefore  生效時間
5. var Exp = DateTime.UtcNow.AddSeconds(1000);  //expires 過期時間
6. string sign = "q2xiARx$4x3TKqBJ"; //SecurityKey 的長度必須 大於等於 16個字符
 var secret = Encoding.UTF8.GetBytes(sign);
 var key = new SymmetricSecurityKey(secret);
 var signcreds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

好了,通過以上填充參數內容,進行傳參賦值得到,完整代碼如下:

新增AuthController.cs控制器:

    [HttpGet]
    public IActionResult GetToken()
    {
        try
        {
            //定義發行人issuer
            string iss = "JWTBearer.Auth";
            //定義受眾人audience
            string aud = "api.auth";

            //定義許多種的聲明Claim,信息存儲部分,Claims的實體一般包含用戶和一些元數據
            IEnumerable<Claim> claims = new Claim[]
            {
                new Claim(JwtClaimTypes.Id,"1"),
                new Claim(JwtClaimTypes.Name,"i3yuan"),
            };
            //notBefore  生效時間
            // long nbf =new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds();
            var nbf = DateTime.UtcNow;
            //expires   //過期時間
            // long Exp = new DateTimeOffset(DateTime.Now.AddSeconds(1000)).ToUnixTimeSeconds();
            var Exp = DateTime.UtcNow.AddSeconds(1000);
            //signingCredentials  簽名憑證
            string sign = "q2xiARx$4x3TKqBJ"; //SecurityKey 的長度必須 大於等於 16個字符
            var secret = Encoding.UTF8.GetBytes(sign);
            var key = new SymmetricSecurityKey(secret);
            var signcreds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var jwt = new JwtSecurityToken(issuer: iss, audience: aud, claims:claims,notBefore:nbf,expires:Exp, signingCredentials: signcreds);
		    var JwtHander = new JwtSecurityTokenHandler();
            var token = JwtHander.WriteToken(jwt);
            return Ok(new
            {
                access_token = token,
                token_type = "Bearer",
            });
        }
        catch (Exception ex)
        {
            throw;
        }
    }
注意:
1.SecurityKey 的長度必須 大於等於 16個字符,否則生成會報錯。(可通過在線隨機生成密鑰)

5. 運行

訪問獲取Token方法,獲取得到access_token:

再訪問,授權資源接口,可以發現,再沒有添加請求頭token值的情況下,返回了401沒有權限。

這次,在請求頭通過Authorization加上之前獲取的token值后,再次進行訪問,發現已經可以獲取訪問資源控制器,並返回對應的數據。

6.擴展說明

在HTTP標準驗證方案中,我們比較熟悉的是”Basic”和”Digest”,前者將用戶名密碼使用BASE64編碼後作為驗證憑證,後者是Basic的升級版,更加安全,因為Basic是明文傳輸密碼信息,而Digest是加密後傳輸。

一、Basic基礎認證

Basic認證是一種較為簡單的HTTP認證方式,客戶端通過明文(Base64編碼格式)傳輸用戶名和密碼到服務端進行認證,通常需要配合HTTPS來保證信息傳輸的安全。

客戶端請求需要帶Authorization請求頭,值為“Basic xxx”,xxx為“用戶名:密碼”進行Base64編碼後生成的值。 若客戶端是瀏覽器,則瀏覽器會提供一個輸入用戶名和密碼的對話框,用戶輸入用戶名和密碼后,瀏覽器會保存用戶名和密碼,用於構造Authorization值。當關閉瀏覽器后,用戶名和密碼將不再保存。

憑證為“YWxhzGRpbjpvcGVuc2VzYWl1”,是通過將“用戶名:密碼”格式的字符串經過的Base64編碼得到的。而Base64不屬於加密範疇,可以被逆向解碼,等同於明文,因此Basic傳輸認證信息是不安全的。

Basic基礎認證圖示:

缺陷匯總
1.用戶名和密碼明文(Base64)傳輸,需要配合HTTPS來保證信息傳輸的安全。
2.即使密碼被強加密,第三方仍可通過加密后的用戶名和密碼進行重放攻擊。
3.沒有提供任何針對代理和中間節點的防護措施。
4.假冒服務器很容易騙過認證,誘導用戶輸入用戶名和密碼。

二、Digest摘要認證

Digest認證是為了修復基本認證協議的嚴重缺陷而設計的,秉承“絕不通過明文在網絡發送密碼”的原則,通過“密碼摘要”進行認證,大大提高了安全性。

Digest認證步驟如下:
第一步:客戶端訪問Http資源服務器。由於需要Digest認證,服務器返回了兩個重要字段nonce(隨機數)和realm。
第二步:客戶端構造Authorization請求頭,值包含username、realm、nouce、uri和response的字段信息。其中,realm和nouce就是第一步返回的值。nouce只能被服務端使用一次。uri(digest-uri)即Request-URI的值,但考慮到經代理轉發后Request-URI的值可能被修改、因此實現會複製一份副本保存在uri內。response也可叫做Request-digest,存放經過MD5運算后的密碼字符串,形成響應碼。
第三步:服務器驗證包含Authorization值的請求,若驗證通過則可訪問資源。
Digest認證可以防止密碼泄露和請求重放,但沒辦法防假冒。所以安全級別較低。
Digest和Basic認證一樣,每次都會發送Authorization請求頭,也就相當於重新構造此值。所以兩者易用性都較差。

Digest認證圖示:

7.注意

  1. 在進行JwtBearer認證時,在生成token之後,還需要與刷新token配合使用,因為當用戶執行了退出,修改密碼等操作時,需要讓該token無效,無法再次使用,所以,會給access_token設置一個較短的有效期間,(JwtBearer認證默認會驗證有效期,通過notBeforeexpires來驗證),當access_token過期后,可以在用戶無感知的情況下,使用refresh_token重新獲取access_token,但這就不屬於Bearer認證的範疇了,但是我們可以通過另一種方式通過IdentityServer的方式來實現,在後續中會對IdentityServer進行詳細講解。
  2. 在生成token的時候,需要用的secret,主要是用來防止token被偽造與篡改。因為當token被劫取的時候,可以得到你的令牌中帶的一些個人不重要的信息明文,但不用擔心,只要你不在生成token里把私密的個人信息放出去的話,就算被動機不良的人得到,也做不了什麼事情。但是你可能會想,如果用戶自己隨便的生成一個 token ,帶上你的信息,那不就可以隨便訪問你的資源服務器了,因此這個時候就需要利用secret 來生成 token,來確保数字簽名的正確性。而且在認證授權資源,進行token解析的時候,通過微軟的源碼發現,已經幫我們封裝了方法,對secret進行了校驗了,確保了token的安全性,從而保證api資源的安全。

8.總結

  1. JwtToken在認證時,無需Security token service安全令牌服務器的參与,都是基於Claim的,默認會驗證有效期,通過notBeforeexpires來驗證,這在分佈式中提供給了極大便利。
  2. JwtToken與平台、無言無關,在前端也可以直接解析出Claims。
  3. 如果有不對的或不理解的地方,希望大家可以多多指正,提出問題,一起討論,不斷學習,共同進步。
  4. 後面會對認證授權方案中的授權這一塊進行說明分享。
  5. 本示例源碼地址
    參考JwtBearer源碼

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

網頁設計一頭霧水該從何著手呢? 台北網頁設計公司幫您輕鬆架站!

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※Google地圖已可更新顯示潭子電動車充電站設置地點!!

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※別再煩惱如何寫文案,掌握八大原則!

網頁設計最專業,超強功能平台可客製化

聚甘新