分類
發燒車訊

手寫jwt驗證,實現java和node無縫切換

前言

前端時間和我寫了一個簡易用戶管理後台,功能其實很簡單,涉及到的技術棧有:vue+elementUI,java+spring MVC以及node+egg,數據庫用的mysql,簡單方便。

一開始是我是只負責前端,但是前端開發的的速度太快,老是沒事,加上他小子並沒有接觸過實戰的項目,又怕他出亂子,所以考慮我也寫一個後端,

開始考慮的是用python+django,但是還是在半途放棄了,因為總感覺Django不過靈活,使用起來非常彆扭,也可能是用scrapy寫爬蟲寫多了,難以理解django的框架設計,總是會把他想象成一個scrapy架構,也導致代碼寫的很亂,下面上一張scrapy架構圖。

所以最後考慮的用node,Express和Koa框架學習過node應該都知道,我以前也用過express(寫過一個小demo),但是給我的感覺這到像是一個只能有5年以上node開發經驗才能玩的轉的,因為express是非常的精簡的,安裝它后,會發現它幾乎不會為你提供任何編碼規範,也沒有約束你的框架應該怎麼設計,以至於新手下載完成后完全不知道自己應該幹嘛,甚至不知道直接的文件應該寫在哪,沒有框架本身的約定,標準的MVC模型有着千奇百怪的寫法,所以我覺得沒有一定的架構思想和經驗是很難駕馭的。

koa我並沒有直接的使用過,只是聽說是express的原班人馬打造的,中間件是基於洋蔥圈模型實現的。下面上一張圖洋蔥圈模型圖。

而是後來直接就接觸的egg,egg標語是“為企業級框架和應用而生”,

廢話說的有點多了,重點是通一套前端代碼,開發了兩套後端代碼,功能是完全一致的,後端都實現了相應的jwt驗證功能,–>,密鑰都是我們約定好的固定值,但是最後發現一樣的密鑰,相同的數據,使用的jwt包不同產生的結果也不同,這也就導致兩端之間無法相互切換,每次切換必須從登陸重新開始,這不太符合邏輯,而且重要的是後面的安排有需要這樣的功能,無法做到無縫切換就直接導致實現不了下面的功能。

提綱內容

  • jwt實現原理
  • jwt未能解決的疑惑
  • base64和base64url

jwt實現原理

其實作為一個前端開發人員,jwt實現原理我是沒必要懂得的,但是如果你不限於此,這算是個必不可少的內容了吧。

先上一張圖。

圖中数字1是後端使用jwt工具包生成的token,通常是由三部分組成,也就是token中間的兩個“.”將其分為三部分,第一部分對應的是右邊的数字2部分,然後依次對應。

這三部分分別是頭部、有效載荷、簽名。

頭部:alg是指說用到的算法,type當然是令牌類型

有效荷載:sub所簽發的用戶,name是簽發者的姓名,lat是這簽發時間,exp是指到期時間,當然還有一些其他的,這些數據都是非必要數據,實則只有exp可能有用,因為有效數據實際都是在data裏面,當然你也可以不這麼做。

簽名:前兩者都是通過base64url編碼過的,而非是算法加密的,所以幾乎是透明的。但是簽名是默認是通過hsa256算法加密的 ,加密的規則是:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  your-256-bit-secret
)

如何驗證token呢?那更加簡單了,就是用前端傳回來的token前兩部分和服務器存的秘鑰再次加密一次,然後做base64url處理和第三部分比較,一樣代表這個token是自己簽發的,不一樣代表是偽造的,完了過後再將有效載荷部分進行base64url反編碼,就得到exp,然後和當前時間比較是否過期。

jwt未能解決的疑惑

經過測試,發現三個問題。

1、 node和java使用對應的jwt工具包生成的token不相同,這裡是指在一系列參數完全相同的情況下。

2、 還發現用java生成的token在jwt官網解析時候輸入秘鑰結果的到的簽名和自己的簽名不一樣,但是node是一樣的,於是就產生了java工具包在輸入簽名的時候對密鑰進行了其他處理的想法,但是他並沒有找出做出來怎麼樣的處理,也就是說我們在生成簽名的時候根本就連密鑰都是不一樣的。

3、 不管是node還是java生成的token,我們用原來一模一樣的數據和一樣的算法公式都產生不了和工具包生成一樣的簽名,也就是可以懷疑在進行hsa256算法加密前確實對秘鑰進行處理了。

base64和base64url

base64就是一種二進制編碼方式,原理很簡單,先準備一個包含64個字符的數組:

['A','B','C',...'a','b','c',...'0','1','2',...'+','/']

然後對二進制數據進行處理,每三個字節一組,一共24bit,一個字節8bit嘛,然後再將24分為4組,每組正好6bit。6bit的話就剛好能表示64個字符。如果編碼字符不是3的倍數,就會剩下一個字節或者兩個字節,這個時候就在後面填充\x00,再在編碼末尾加上一個或者兩個=號。解碼的時候制動力去掉就好了。

base64url編碼就是將字符編碼成url能傳遞的參數,因為base64編碼會出現+號和/號,然後就會在url中出現問題,所以base64url其實就是將+和/分別變成-和_

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

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

分類
發燒車訊

go中的數據結構-切片slice

1. 部分基本類型

  go中的類型與c的相似,常用類型有一個特例:byte類型,即字節類型,長度為,默認值是0;

1 bytes = [5]btye{'h', 'e', 'l', 'l', 'o'}

  變量bytes的類型是[5]byte,一個由5個字節組成的數組。它的內存表示就是連起來的5個字節,就像C的數組。

1.1 字符串

  字符串在Go語言內存模型中用一個2字長(64位,32位內存布局方式下)的數據結構表示。它包含一個指向字符串數據存儲地方的指針,和一個字符串長度數據如下圖:

  s是一個string類型的字符串,因為string類型不可變,對於多字符串共享同一個存儲數據是安全的。切分操作str[i:j]會得到一個新的2字長結構t,一個可能不同的但仍指向同一個字節序列(即上文說的存儲數據)的指針和長度數據。所以字符串切分不涉及內存分配或複製操作,其效率等同於傳遞下標。

1.2 數組

  數組是內置(build-in)類型,是一組同類型數據的集合,它是值類型,通過從0開始的下標索引訪問元素值。數組類型定義了長度和元素類型。如, [4]int 類型表示一個四個整數的數組,其長度是固定的,長度是數組類型的一部分( [4]int 和 [5]int 是完全不同的類型)。 數組可以以常規的索引方式訪問,表達式 s[n] 訪問數組的第 n 個元素。數組不需要顯式的初始化;數組的零值是可以直接使用的,數組元素會自動初始化為其對應類型的零值。

1  var a [4]int
2  a[0] = 1
3  i := a[0]
4  // i == 1
5  // a[2] == 0, int 類型的零值
6 [5] int {1,2}  //長度為5的數組,其元素值依次為:1,2,0,0,0 。在初始化時沒有指定初值的元素將會賦值為其元素類型int的默認值0,string的默認值是"" 
7 [...] int {1,2,3,4,5}  //長度為5的數組,其長度是根據初始化時指定的元素個數決定的 
8 [5] int { 2:1,3:2,4:3}  //長度為5的數組,key:value,其元素值依次為:0,0,1,2,3。在初始化時指定了2,3,4索引中對應的值:1,2,3 
9 [...] int {2:1,4:3}  //長度為5的數組,起元素值依次為:0,0,1,0,3。由於指定了最大索引4對應的值3,根據初始化的元素個數確定其長度為5賦值與使用

  Go的數組是值語義。一個數組變量表示整個數組,它不是指向第一個元素的指針(不像 C 語言的數組)。 當一個數組變量被賦值或者被傳遞的時候,實際上會複製整個數組。 (為了避免複製數組,你可以傳遞一個指向數組的指針,但是數組指針並不是數組。) 可以將數組看作一個特殊的struct,結構的字段名對應數組的索引,同時成員的數目固定。

b := [2]string{"Penn", "Teller"}
b := [...]string{"Penn", "Teller"}

  這兩種寫法, b 都是對應 [2]string 類型。

2. 切片slice 

2.1 結構

  切片類型的寫法是[]T ,T是切片元素的類型。和數組不同的是,切片類型並沒有給定固定的長度。切片的字面值和數組字面值很像,不過切片沒有指定元素個數,切片可以通過數組來初始化,也可以通過內置函數make()初始化。

letters := []string{"a", "b", "c", "d"}   //直接初始化切片,[]表示是切片類型,{"a", "b", "c", "d"},初始化值依次是a,b,c,d.其cap=len=4
s := letters [:]  //初始化切片s,是數組letters的引用(a slice referencing the storage of x)
func make([]T, len, cap) []T    //使用內置函數 make 創建
s :=make([]int,len,cap)    //通過內置函數make()初始化切片s,[]int 標識為其元素類型為int的切片
s := arr[startIndex:endIndex]   //將arr中從下標startIndex到endIndex-1 下的元素創建為一個新的切片
s := arr[startIndex:]   //缺省endIndex時將表示一直到arr的最後一個元素
s := arr[:endIndex]   //缺省startIndex時將表示從arr的第一個元素開始
s1 := s[startIndex:endIndex]   //通過切片s初始化切片s1

  slice可以從一個數組或一個已經存在的slice中再次聲明。slice通過array[i:j]來獲取,其中i是數組的開始位置,j是結束位置,但不包含array[j],它的長度是j-i

1 var ar = [10]byte{'a','b','c','d','e','f','g','h','i','j'}   // 聲明一個含有10個元素元素類型為byte的數組
2 var a, b []byte  // 聲明兩個含有byte的slice
3 a = ar[2:5]  //現在a含有的元素: ar[2]、ar[3]和ar[4]
4  
5 // b是數組ar的另一個slice
6 b = ar[3:5]// b的元素是:ar[3]和ar[4]

  一個slice是一個數組某個部分的引用。在內存中它是一個包含三個域的結構體:指向slice中第一個元素的指針ptr,slice的長度數據len,以及slice的容量cap。長度是下標操作的上界,如x[i]中i必須小於長度。容量是分割操作的上界,如x[i:j]中j不能大於容量。slice在Go的運行時庫中就是一個C語言動態數組的實現,在$GOROOT/src/pkg/runtime/runtime.h中定義:

struct    Slice
{    // must not move anything
    byte*    array;        // actual data
    uintgo    len;        // number of elements
    uintgo    cap;        // allocated number of elements
};

  數組的slice會創建一份新的數據結構,包含一個指針,一個指針和一個容量數據。如同分割一個字符串,分割數組也不涉及複製操作,它只是新建了一個結構放置三個數據。如下圖:

  示例中,對[]int{2,3,5,7,11}求值操作會創建一個包含五個值的數組,並設置x的屬性來描述這個數組。分割表達式x[1:3]不重新分配內存數據,只寫了一個新的slice結構屬性來引用相同的存儲數據。上例中,長度為2–只有y[0]和y[1]是有效的索引,但是容量為4–y[0:4]是一個有效的分割表達式。

  因為slice分割操作不需要分配內存,也沒有通常被保存在堆中的slice頭部,這種表示方法使slice操作和在C中傳遞指針、長度對一樣廉價。

2.2 擴容

  其實slice在Go的運行時庫中就是一個C語言動態數組的實現,要增加切片的容量必須創建一個新的、更大容量的切片,然後將原有切片的內容複製到新的切片。在對slice進行append等操作時,可能會造成slice的自動擴容。其擴容時的大小增長規則是:

  • 如果新的大小是當前大小2倍以上,則大小增長為新大小
  • 否則循環以下操作:如果當前大小小於1024,按每次2倍增長,否則每次按當前大小1/4增長。直到增長的大小超過或等於新大小。

  下面的例子將切片 s 容量翻倍,先創建一個2倍 容量的新切片 t ,複製 s 的元素到 t ,然後將 t 賦值給 s : 

t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
for i := range s {
        t[i] = s[i]
}
s = t

  循環中複製的操作可以由 copy 內置函數替代,返回複製元素的數目。此外, copy 函數可以正確處理源和目的切片有重疊的情況。

一個常見的操作是將數據追加到切片的尾部。必要的話會增加切片的容量,最後返回更新的切片:

func AppendByte(slice []byte, data ...byte) []byte {
    m := len(slice)
    n := m + len(data)
    if n > cap(slice) { // if necessary, reallocate
        // allocate double what's needed, for future growth.
        newSlice := make([]byte, (n+1)*2)
        copy(newSlice, slice)
        slice = newSlice
    }
    slice = slice[0:n]
    copy(slice[m:n], data)
    return slice
}

  Go提供了一個內置函數 append,也實現了這樣的功能。

func append(s []T, x ...T) []T
//append 函數將 x 追加到切片 s 的末尾,並且在必要的時候增加容量。
a := make([]int, 1)
// a == []int{0}
a = append(a, 1, 2, 3)
// a == []int{0, 1, 2, 3}

  如果是要將一個切片追加到另一個切片尾部,需要使用 ... 語法將第2個參數展開為參數列表。

a := []string{"John", "Paul"}
b := []string{"George", "Ringo", "Pete"}
a = append(a, b...) // equivalent to "append(a, b[0], b[1], b[2])"
// a == []string{"John", "Paul", "George", "Ringo", "Pete"}

  由於切片的零值 nil 用起來就像一個長度為零的切片,我們可以聲明一個切片變量然後在循環 中向它追加數據:

// Filter returns a new slice holding only
// the elements of s that satisfy fn()
func Filter(s []int, fn func(int) bool) []int {
    var p []int // == nil
    for _, v := range s {
        if fn(v) {
            p = append(p, v)
        }
    }
    return p
}

3. 使用切片需要注意的陷阱

  切片操作並不會複製底層的數組。整個數組將被保存在內存中,直到它不再被引用。 有時候可能會因為一個小的內存引用導致保存所有的數據。

  如下, FindDigits 函數加載整個文件到內存,然後搜索第一個連續的数字,最後結果以切片方式返回。

var digitRegexp = regexp.MustCompile("[0-9]+")

func FindDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    return digitRegexp.Find(b)
}

  這段代碼的行為和描述類似,返回的 []byte 指向保存整個文件的數組。因為切片引用了原始的數組, 導致 GC 不能釋放數組的空間;只用到少數幾個字節卻導致整個文件的內容都一直保存在內存里。要修復整個問題,可以將需要的數據複製到一個新的切片中:

func CopyDigits(filename string) []byte {
    b, _ := ioutil.ReadFile(filename)
    b = digitRegexp.Find(b)
    c := make([]byte, len(b))
    copy(c, b)
    return c
}

  使用 append 實現一個更簡潔的版本:

    8  func CopyDigitRegexp(filename string) []byte {
    7     b,_ := ioutil.ReadFile(filename)
    6     b = digitRefexp.Find(b)
    5     var c []intb
    4    // for _,v := range b{
    3         c =append(c, b)
    2     //}
    1     return c
    0  }

4. make和new

Go有兩個數據結構創建函數:make和new,也是兩種不同的內存分配機制。

make和new的基本的區別是new(T)返回一個*T,返回的是一個指針,指向分配的內存地址,該指針可以被隱式地消除引用)。而make(T, args)返回一個普通的T。通常情況下,T內部有一些隱式的指針。所以new返回一個指向已清零內存的指針,而make返回一個T類型的結構。更詳細的區別在後面內存分配的學習里研究。

5. 數組和切片的區別

  • 數組長度不能改變,初始化后長度就是固定的;切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。
  • 結構不同,數組是一串固定數據,切片描述的是截取數組的一部分數據,從概念上說是一個結構體。
  • 初始化方式不同,如上。另外在聲明時的時候:聲明數組時,方括號內寫明了數組的長度或使用...自動計算長度,而聲明slice時,方括號內沒有任何字符。
  • unsafe.sizeof的取值不同,unsafe.sizeof(slice)返回的大小是切片的描述符,不管slice里的元素有多少,返回的數據都是24。unsafe.sizeof(arr)的值是在隨着arr的元素的個數的增加而增加,是數組所存儲的數據內存的大小。

  unsafe.sizeof總是在編譯期就進行求值,而不是在運行時,這意味着,sizeof的返回值可以賦值給常量。  在編譯期求值,還意味着可以獲得數組所佔的內存大小,因為數組總是在編譯期就指明自己的容量,並且在以後都是不可變的。

  unsafe.sizeof(string)時大小始終是16,不論字符串的len有多大,sizeof始終返回16,這是因為字符串類型對應一個結構體,該結構體有兩個域,第一個域是指向該字符串的指針,第二個域是字符串的長度,每個域佔8個字節,但是並不包含指針指向的字符串的內容。

6. nil

  按照Go語言規範,任何類型在未初始化時都對應一個零值:布爾類型是false,整型是0,字符串是””,而指針,函數,interface,slice,channel和map的零值都是nil。

interface

  一個interface在沒有進行初始化時,對應的值是nil。也就是說var v interface{},此時v就是一個nil。在底層存儲上,它是一個空指針。與之不同的情況是,interface值為空。比如:

1 var v *T
2 var i interface{}
3 i = v

  此時i是一個interface,它的值是nil,但它自身不為nil。

string

  string的空值是””,它是不能跟nil比較的。即使是空的string,它的大小也是兩個機器字長的。slice也類似,它的空值並不是一個空指針,而是結構體中的指針域為空,空的slice的大小也是三個機器字長的。

channel

  channel跟string或slice有些不同,它在棧上只是一個指針,實際的數據都是由指針所指向的堆上面。

  跟channel相關的操作有:初始化/讀/寫/關閉。channel未初始化值就是nil,未初始化的channel是不能使用的。下面是一些操作規則:

  • 讀或者寫一個nil的channel的操作會永遠阻塞。
  • 讀一個關閉的channel會立刻返回一個channel元素類型的零值。
  • 寫一個關閉的channel會導致panic。

map

  map也是指針,實際數據在堆中,未初始化的值是nil。

 

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

【其他文章推薦】

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

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

分類
發燒車訊

計算機專業學生常用網站

這篇文章我很早之前就想寫了,但奈何一直沒有合適的時間,也不知道應該怎樣去表達。現在自己是一個大三的學生,學習了兩年多的計算機,我不知道自己算不算合格,和那些初中就搞OI,大三實習就業的大佬們相比,我肯定是不行的,但我覺得我這兩年的學習經歷應該更符合一般的計算機專業學生,可能也更有參考性吧。這裏我主要來分享一下我常用的一些網站,這些網站主要受眾還是學生,關注我的人也大都是同輩的學生,大家可以在評論區討論或補充,這篇博客也會一直更新下去。

1、Google

這個網站就不必說了吧,我一直有一種觀點,搜索資料對計算機專業的學生來說是一種特別重要的能力。現在的世界有那麼多的知識,誰也不可能都學會,咱們的大腦只是一個cache級別的存儲器,想要獲得知識、解決問題,學會使用搜索引擎必不可少!至於google被牆,使用百度也是可以的,但注意對信息要辨偽存真,多去比較。

2、GitHub

這是開發者最為重要的網站了吧,代碼託管網站。大概大一下學期才注意到這個網站,各種資源應有盡有,想要什麼輪子,上去搜就好了。最令我震驚的是,裏面還有這種網課學習資料,清華北大浙大等名校計算機專業所有課程的資料都齊全,互聯網時代真的太便利了。

 

3、Stack Overflow

這個網站也挺有用的,之前我查找一個C++問題,搜索的結果都答不到點上,在上面看到一個美國人的回答才如夢初醒。後來學習過程中遇到什麼 問題,上去搜一下,大概率能搜到答案。缺點也很明顯,這是一個英語網站,大多數回答都是英文,所以要有點計算機英語基礎。至於同樣英文網站的GitHub,我只能感慨,中國程序員太厲害了,中文項目一點也不少,可以說GitHub的繁榮離不開中國人。

 

4、bilibili

或許最初這隻是一個二次元愛好者的聚集地,但現在B站應該可以算是中國的油管吧。我在高中的時候入坑B站,申請會員需要答題就讓我知道這個網站應該有着素質不錯的成員,果然這裡有無數的沙雕網友逗你開心,逛B站也成為我高中生活最快樂的消遣方式。上了大學才發現B站也可以是一個學習網站,甚至中央都表揚過B站。跟着B站上的老師學了高數、離散數學、線性代數、数字邏輯、概率論、計算機組成原理等等,我一般是在課堂上聽一遍,課後快到考試周了跟着B站視頻複習一遍,很穩!我愛死這個小破站了!(不知道大家有沒有注意到我博客背景上的22娘33娘呢?)

5、中國大學MOOC

 這個算是對B站的一個補充的,其實B站中很多學校視頻都是轉自這裏的,很多網課其實是侵權的,隨時可能被B站刪掉。雖然有些可能需要收費,但也還能接受,至少質量有保證。

6、知乎

為什麼要提知乎這個看似很無關的網站?我主要覺得這是一個可以用來增長見識的社區,雖然現在它一點點的向微博貼吧靠近。

知乎給自己的定位是一個網絡問答社區,用戶在上面分享自己專業的知識和見解。據統計與計算機相關的用戶佔總用戶很大的比重,可能大家上班都在划水?

也有很多大佬直接在知乎上寫博客,平時逛逛知乎把握一下行業動向,聽聽大佬吹吹牛逼,很有意思。

7、博客園

這個我立足的地方嘛!我在大一下學期才正式開始寫博客,最初搞ACM,師哥讓我們寫題解,最開始真是不愛寫,隨便應付一下,後來發現寫博客的樂趣,一發不可收拾。每天逛一下,大家說話有好聽,我超級喜歡這裏!

8、CSDN

這應該是一個邁不過去的話題吧,我也不想修什麼優越感,但是現在CSDN真的令人不悅呀!以前聽前輩講起過它的輝煌,現在也不能說是沒落了吧,依舊有龐大的用戶,龐大的流量,也算是一個成功的商業網址了。CSDN最讓我反感的一點是找一個問題,所有答案都是一樣複製粘貼過來的,很難找到原作者,問轉載者詳情問題詳情也無法解答。我不反對轉載別人的博客,畢竟要有開源精神,但轉載能不能貼一個原文鏈接?還有積分下載,講一個笑話,我一個師哥發了一份JDK1.8,5C幣下載,一年賺了300C幣,這是在收智商稅?

9、MSDN 我告訴你

這個網站可就厲害了,整合了許多微軟原版系統鏡像,精簡版本,純凈系統。

10、W3school

就算不去學前端,我們多多少少也要了解一些相關知識,這也算是一個前端只是比較全的網站了。

11、鳩摩搜索

能夠搜索出不少專業書,配合pandownload使用吧,這個給出pandownload的使用說明

12、菜鳥教程

 

 有朋友提到了菜鳥教程,這裏也來介紹一下吧,個人覺得菜鳥教程提供了較為全面,系統詳細的教程,廣告少,界面簡約,聽說網站最早是一個人寫的,很牛。這個網站挺適合新手做輔助,個人覺得就是有些教程獲取不到較為詳細的說明。

13、各大OJ

北京大學

杭州电子科技大學

浙江大學

codeforces

PAT

藍橋杯

 

 

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

【其他文章推薦】

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

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

分類
發燒車訊

Net Core Identity 身份驗證:註冊、登錄和註銷 (簡單示例)

一、前言

  一般我們自己的系統都會用自己設置的一套身份驗證授權的代碼,這次用net core的identity來完成簡單的註冊、登錄和註銷。

二、數據庫

  首先就是創建上下文,我這裏簡單的建了Users和UserClaim表,要是沒有UserClaim等下的登錄操作是會報錯的,應該是有身份認證方面的關係。

    public class DataBaseContext : DbContext
    {
        public DataBaseContext(DbContextOptions<DataBaseContext> options)
        : base(options)
        { }
        public DbSet<User> Users { get; set; }
        public DbSet<IdentityUserClaim<string>> UserClaim { get; set; }
    }
    public class User : IdentityUser
    {
        public string companyId { get; set; }
        public string PassWord { get; set; }
    }

  這裏User繼承了IdentityUser,IdentityUser中就用很多的基礎字段,像是UserName等所以我們可以再User類中擴展我們的字段。

  add-migration Init和update-database Init再控制台執行,生成表。

三、Startup註冊服務

  在ConfigureServices中註冊如下

  1、數據庫上下文連接

  //添加數據庫連接
  services.AddDbContext<DataBaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

  2、添加標識服務,包括默認的UI、令牌提供和身份驗的cookie,並且添加identity信息存儲的實體框架實現,用於關聯數據庫創建用戶獲取用戶信息等。AddDefaultIdentity一個相當於AddIdentity、AddDefaultUI和AddDefaultTokenProviders三個。如果User不繼承IdentityUser使用AddEntityFrameworkStores會報錯。

  services.AddDefaultIdentity<User>().AddEntityFrameworkStores<DataBaseContext>();

  3、添加Identity的選項,可以設定密碼的強度、長度、使用字符、密碼輸入錯誤次數等等。

    services.Configure<IdentityOptions>(options =>
    {
        // 密碼設置
        options.Password.RequireDigit = false;
        options.Password.RequireLowercase = false;
        options.Password.RequireNonAlphanumeric = false;
        options.Password.RequireUppercase = false;
        options.Password.RequiredLength = 1;
        options.Password.RequiredUniqueChars = 1;

        // 鎖定設置
        options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5);
        options.Lockout.MaxFailedAccessAttempts = 5;
        options.Lockout.AllowedForNewUsers = true;

        // 用戶設置
        options.User.AllowedUserNameCharacters =
        "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+";
        options.User.RequireUniqueEmail = false;
    });

  4、配置應用程序的cookie

    services.ConfigureApplicationCookie(options =>
    {
        // Cookie設置
        options.Cookie.HttpOnly = true;
        options.ExpireTimeSpan = TimeSpan.FromMinutes(5);

        options.LoginPath = "/Login/Index";
        options.AccessDeniedPath = "/Home/Index";
        options.SlidingExpiration = true;
    });

  在Config中註冊身份認證

  app.UseAuthentication();

四、簡單的登錄、註冊和註銷

  既然是簡單的例子,那我是真的怎麼簡單怎麼來,代碼也就沒幾條。

  先創建一個Home控制器並加上[Authorize]特性,沒得到驗證的就統統無法訪問。按照上面的Startup.cs已經將UserManager依賴注入了,它是用來管理用戶的比如註冊啥的。

  [Authorize]
    public class HomeController : Controller
    { 
        private UserManager<User> userManager;public HomeController(UserManager<User> _userManager)
        {
            userManager = _userManager;
        }
        public async Task<IActionResult> Index()
        {
            var res = await userManager.GetUserAsync(HttpContext.User);
            return View();
        }
    }

  然後創建一個Login控制器,我們可以在裏面寫登錄、註冊和註銷的方法。Login控制器除了UserManager外還要注入SignManager,它是用來用戶登錄、註銷等操作的。

    public class LoginController : Controller
    {
        //用於提供持久性存儲的用戶信息
        private UserManager<User> userManager;
        private SignInManager<User> signManager;
        public LoginController(UserManager<User> _userManager,SignInManager<User> _signManager)
        {
            userManager = _userManager;
            signManager = _signManager;
        }
    }

  1、註冊

   註冊直接用CreateAsync方法,會自動在數據庫創建用戶。SignInAsync方法用於剛註冊的馬上用戶登錄。

        public async Task<IActionResult> Register()
        {
            var user = new User() { UserName = "xu2", PhoneNumber = "123", companyId = "1" };
            var result = await userManager.CreateAsync(user, "123");
            await signManager.SignInAsync(user, true);
            if (result.Succeeded)
                return Redirect("/Home/Index");
            return Redirect("/Login/Index");
        }

  2、登錄

  登錄不能用SignInAsync了,要用PasswordSignInAsync密碼登錄

        public async Task<IActionResult> Index()
        {
            var s = await signManager.PasswordSignInAsync("xu", "123", true, false);
            return View();
        }

  3、註銷

  這邊直接return view()是無法註銷的,因為cookie會被重新加載,需要return Redirect(“/Home/Index”)重定向

        public async Task<IActionResult> LogOut()
        {
            await signManager.SignOutAsync();
            return View();
        }

  4、獲取當前登錄用戶

    var res = await userManager.GetUserAsync(HttpContext.User);

 

 

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

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

分類
發燒車訊

MapReduce任務提交源碼分析

  為了測試MapReduce提交的詳細流程。需要在提交這一步打上斷點:

   F7進入方法:

   進入submit方法:

   注意這個connect方法,它在連接誰呢?我們知道,Driver是作為客戶端存在的,那麼客戶端連接的應該就是Yarn集群,但是在這個簡單的WordCount案例中,並沒有將任務提交到Yarn集群,而是在本機中執行的。所以先假設這裏連接的自然就是本機。

進入這個connect方法,然後在裏面的Cluster(集群的意思)方法上打上斷點:

 

 很明顯,這是一個構造器,他把集群抽象成了一個對象。進入此方法:

 初始化了一個客戶端協議,進入這個create方法,看看他是如何初始化客戶端協議的:

   注意這個mapreduce.framework.name,他就是mapred-site.xml文件中的mapreduce.framework.name項的值,由於我並沒有提交到集群上,而是在本機,所以他會加載本機的mapred-site.xml文件,但是我本機下的該文件並沒有像集群上那樣配置了mapred-site.xml文件,只有一份mapred-site.xml.template文件,更沒有mapreduce.framework.name這一項,所以上面代碼中的值就默認為local了。

  本機上的配置:

 集群上的配置:

create方法最終反回了一個LocalJobRunner對象,如果上面的值是yarn,返回的則是YarnJobRunner。繼續往下:

   會發現這個LocalJobRunner就是客戶端。然後一直往下,直到完成connect方法,會發現整個過程中在connect方法中創建了一個Cluster對象,然後在Cluster對象裏面獲取到了客戶端。

  緊接着,由於connect方法初始化了cluster對象,所以接下來創建了submitter對象,用於提交任務。進入submitJobInternal方法打上斷點

 

這個checkSpecs方法就是用來檢查路徑的,當輸入路徑不存在或輸出路徑已存在時會報錯。進入此方法后再進入內部方法就一目瞭然了:

 

繼續往下執行,完成checkSpecs方法后完初始化一個路徑:

打開此路徑,此時還是空的文件夾:

繼續往下,隨後做了一些獲取IP和往配置文件中設置IP和hostname的操作:

 繼續往下,隨後又在上面的路徑下隨機創建了一個目錄:

繼續往下,見到copyAndConfigureFiles時,進入此方法,然後在進入內部方法uploadFiles():

在uploadFiles方法中有,執行后的效果:

 

 

 

 

 這個文件夾暫時不知道幹嘛的,只知道copyAndConfigureFiles方法創建了這個路徑。此方法執行完后,執行到writeSplits進入此方法:

 這個方法是重點:切片是怎麼切的呢?

 maps是int型,這表示這啟動的maptask的數量也該和切片的數量保持一致。而具體切成多少片呢?

上面的方法多態調用到子類的方法writeNewSplits,然後調用getSplits方法:

getSplits方法中有這樣一段:

   也就是說:當剩餘長度比切片尺寸大於1.1時,就會產生新的切片,比如說文件65m,splitSize為32m,第一片切到32m,剩餘33m,由於33/32<1.1,所以就不再切片,65m被切成兩片,0~32、32~65,而不是0~32 、 32~64 、 64~65三片。

   當執行完writeSplits方法后,會在上面創建的目錄下生成幾個文件:

 上面生成的文件中保存了“切片的規劃信息”。繼續往下,當執行到writeConf方法后,會繼續在上面的目錄下生成與此Job相關的配置文件:

 

   繼續執行,當執行完submitJob方法后,job本身(即WordCount程序本身會被打成jar包被提交)就被提交了:

  但是由於我是直接在本地執行的,直接從main方法進來執行的,沒必要再打成jar包再從main方法進入,所以並不用提交,但是如果是是在yarn 上執行的時候,會把程序打成jar包放在上面的目錄下。

   當任務執行完畢后,上面的目錄會被清空:

   至此,整個任務的提交執行完成,試想一下,如果這個任務在Yarn上執行是什麼樣子呢?基本的邏輯不會變:

  首先,還是執行connect方法,初始化到Cluster對象,然後創建JobRunner,不過在Yarn上執行的JobRunner就不是LocalJobRunner了,而是YarnJobRunner。執行完connect方法後會在HDFS文件系統創建一個路徑,其作用與上面創建的路徑相同,用於保存切片方案信息和配置文件信息,同時會將任務本身的jar包放入其中,最後任務執行完,這些內容又將被銷毀。

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

【其他文章推薦】

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

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

分類
發燒車訊

酒精製環保清潔劑 跨界合作友善環境

摘錄自2019年12月13日公視報導

「無酒精」啤酒近年來越來越受歡迎,不過大量酒精廢棄物何去何從,讓業者傷腦筋。有啤酒製造商和清潔劑公司合作,將這類廢棄物用來製造環保洗碗精。

總部設在比利時魯汶的百威英博啤酒集團,是全球最大的啤酒製造商。為了迎合快速成長的無酒精啤酒市場的需求,業者生產這種喝了不醉的飲料時,得將酒精提取出來。不過大量廢棄酒精何去何從?一直讓業者很頭痛。

百威英博後來找上強調使用天然配方的環保清潔產品製造商宜珂,發現將廢棄酒精淨化再處理後,可以用作活性清潔劑和防腐劑成分,雙方一拍即合。不過廢酒精再利用,仍舊會散發酒的味道,宜珂正想盡辦法克服。宜珂創新部主任多曼說:「如何蓋住這個味道,讓我們的產品在消費者使用時聞起來味道很好。因為消費者不希望餐具上留有啤酒味,所以這是我們主要的挑戰。」

宜珂後來使用來自其他廢棄農產品提煉的香味,掩蓋啤酒味,成功推出這款環保洗碗精,上面標註有1/4成分來自啤酒廢棄物。從啤酒泡到清潔劑泡泡,百威英博成功將產業垃圾再利用,透過跨界合作,變成對環境更友善的商品。

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

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

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

分類
發燒車訊

瞄準2050碳中和 歐盟綠色政綱出爐 強調「公正轉型」值得台灣借鏡

環境資訊中心記者 陳文姿報導;姜唯編譯 林大利審校

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

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

分類
發燒車訊

荷蘭工黨提案於 2025 年禁售汽柴油車

汽柴油車開在路上,產生氮氧化物、未燃燒完全的碳氫化合物、一氧化碳,以及如今相當受重視的 PM2.5 微粒等等空氣污染,如今在全球減碳風潮下,產生的二氧化碳也遭嚴格檢視,尤其在大量能源已經來自可再生能源的數個歐洲國家,汽車排放成為減碳的最大目標之一,荷蘭執政聯盟中的工黨(Partij van de Arbeid,PvdA),提案要求 2025 年禁止所有汽柴油車,而此動議已經提交眾議院。   在這項動議中,至 2025 年荷蘭將禁用所有燃油車輛,不只是全汽柴油車,連同油電混合車也將禁止,也就是說只剩下車輛本身完全無二氧化碳的純電動車與燃料電池車。除此之外,動議還針對減輕荷蘭的交通阻塞狀況,而要求政府積極推動自動駕駛車輛。   在以燃煤為電力大宗來源的國家中,發展純電動車對減碳並不具效益,因為電動車的電力仍然來自燃煤發電,仍然是間接產生大量二氧化碳,但若是電力已經以可再生能源為主,那麼發展電動車可望減少交通方面的二氧化碳排放量。而氫燃料電池車輛是否減碳,則視氫來源而定,許多工業如石化、造紙等產業可回收產製大量氫,而氫也可以是生質能源,如許多技術能從有機廢棄物或排泄物中製氫,從這些方式得到的氫不僅成本較低,也確實能減少總碳排放量,但若以電力製氫,則也是要看電力來源為何。   以荷蘭來說,其實電力主要仍然來自火力發電,以 2015 年 9 月而言,燃煤發電佔總用電量約 49%,燃氣發電約 31%,而全數可再生能源含風力、太陽能、生質能為 9.7%,雖然較 2014 年的 7.2% 有所提升,但比率仍低,核能則為 3.9 %,此外進口電力 2.9%,大多是來自挪威的水力發電。因此,荷蘭目前若推動全電動車與燃料電池車輛,對減碳的實質助益並不大,須配合電力來源也同時全力轉換為可再生能源。   荷蘭執政聯盟中的另一大黨自由民主人民黨(Volkspartij voor Vrijheid en Democratie,VVD)就對此提案表達反對,表示完全禁止燃油車輛「野心太大、不切實際」,該黨經濟部長認為電動車市佔率最好是 15%,超過這個比率,電力管理可能會有問題,工黨的部分議員也抱怨「看報紙才知道」此項提案。不過,工黨提案議員則反駁批評,表示這項提案是讓人民思考未來如何擺脫汽車排氣管的排放污染的面向之一,一瞥國家未來無限可能的發展想像。   這項提案最終實際通過成為法案的可能性很低,不過出現這樣的提案也顯示,類似想法雖然暫時仍「不切實際」,卻已經有許多人開始考慮,未來在各國電力系統持續現代化,提升可再生能源比率,各種電網技術進步將強化電網調度能力,日後再出現類似提案,實際通過機率將逐漸提升,而汽柴油車到時就得真的開始緊張了。   (本文內容由授權使用;首圖來源:)

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

【其他文章推薦】

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

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務

分類
發燒車訊

亞洲首輛純電動垃圾車在台南展開清運服務

四家經驗豐富的台灣電動車廠商合作,開發出全亞洲第一輛純電動垃圾清運車,並於台南展開清運服務。這輛純電動垃圾車具「三零一低」的特性:零耗油、零排碳、零怠速、低噪音,具有極高經濟效益。

電動垃圾車廠商同均動能結合富田電機、利佳興業、立淵機械等三家公司,在經濟部工業局的計劃支持下,歷經兩年研發成功推出全亞洲首輛純電動垃圾清運車。垃圾車具有走停頻繁、車速慢的特色,且有壓縮垃圾的功能需求。傳統柴油垃圾車在低速行駛與剎車啟動時都會排放較多廢氣,且壓縮垃圾時也需啟動引擎來帶動壓縮力道,造成更嚴重的廢氣與噪音汙染。相較之下,電動垃圾車可改善上述問題,讓垃圾清運的過程更加舒適環保。

這輛純電動垃圾車將於台南定時定點巡迴於鄉間與都市,執行垃圾清運任務,貫徹「綠色環境、低碳台灣」的理念。

(圖片來源:翻攝同均動能)

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

【其他文章推薦】

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!!

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

※幫你省時又省力,新北清潔一流服務好口碑

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

分類
發燒車訊

工信部與重慶簽訂啟動智慧汽車與智慧交通合作協議

1月27日,中國工業和資訊化部、重慶市人民政府在重慶簽訂“基於寬頻移動互聯網的智慧汽車與智慧交通應用示範合作框架協定”,將共同推動構建4.5G/5G、智慧汽車與智慧交通融合發展的產業生態。

根據合作框架協定和建設方案,工業和資訊化部、重慶市人民政府將共同推動構建4.5G/5G、智慧汽車與智慧交通融合發展的產業生態,研發一批智慧汽車與智慧交通關鍵技術和產品,帶動電子資訊、寬頻移動通信、移動互聯網、物聯網、汽車製造等相關產業的發展。

未來三年,重慶市將逐步由試驗場區封閉環境到城市交通開放環境,加強關於自動駕駛、交通安全、舒適及節能環保、資訊服務及娛樂、交通管理等領域的新技術、新產品研究開發和檢測認證。重慶將在智慧駕駛、智慧路網、綠色用車、防盜追蹤、便捷停車、車與車的資源分享、大範圍交通誘導、交通狀態智慧管理等多個方面進行應用示範。

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

【其他文章推薦】

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

網頁設計一頭霧水??該從何著手呢? 找到專業技術的網頁設計公司,幫您輕鬆架站!

※想要讓你的商品成為最夯、最多人討論的話題?網頁設計公司讓你強力曝光

※想知道最厲害的台北網頁設計公司推薦台中網頁設計公司推薦專業設計師”嚨底家”!!

新北清潔公司,居家、辦公、裝潢細清專業服務