日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢(xún)
選擇下列產(chǎn)品馬上在線(xiàn)溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
用Go模擬實(shí)現(xiàn)單點(diǎn)登錄Token生成和驗(yàn)證解析

1.單點(diǎn)登錄(SSO)原理

單點(diǎn)登錄(Single Sign-On,簡(jiǎn)稱(chēng)SSO)是一種身份驗(yàn)證和授權(quán)機(jī)制,允許用戶(hù)在訪(fǎng)問(wèn)多個(gè)相關(guān)獨(dú)立的系統(tǒng)或應(yīng)用程序時(shí)只需一次登錄, 而不需要為每個(gè)系統(tǒng)都提供單獨(dú)的身份驗(yàn)證憑證。SSO的目的是簡(jiǎn)化用戶(hù)體驗(yàn)、提高安全性, 并減少用戶(hù)因頻繁登錄而可能面臨密碼疲勞問(wèn)題。

我們注重客戶(hù)提出的每個(gè)要求,我們充分考慮每一個(gè)細(xì)節(jié),我們積極的做好做網(wǎng)站、成都網(wǎng)站建設(shè)服務(wù),我們努力開(kāi)拓更好的視野,通過(guò)不懈的努力,成都創(chuàng)新互聯(lián)公司贏得了業(yè)內(nèi)的良好聲譽(yù),這一切,也不斷的激勵(lì)著我們更好的服務(wù)客戶(hù)。 主要業(yè)務(wù):網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)站設(shè)計(jì),小程序開(kāi)發(fā),網(wǎng)站開(kāi)發(fā),技術(shù)開(kāi)發(fā)實(shí)力,DIV+CSS,PHP及ASP,ASP.Net,SQL數(shù)據(jù)庫(kù)的技術(shù)開(kāi)發(fā)工程師。

SSO的工作原理涉及以下關(guān)鍵概念:

  • 身份提供者(Identity Provider, IdP): 負(fù)責(zé)驗(yàn)證用戶(hù)的身份并生成令牌(Token)。IdP通常是一個(gè)中心化的認(rèn)證系統(tǒng), 負(fù)責(zé)向其他相關(guān)系統(tǒng)提供認(rèn)證服務(wù)。
  • 服務(wù)提供者(Service Provider, SP): 各個(gè)系統(tǒng)或應(yīng)用程序, 它們依賴(lài)于IdP來(lái)驗(yàn)證用戶(hù)身份。SP接收到IdP頒發(fā)的令牌后, 可以通過(guò)驗(yàn)證令牌的有效性來(lái)信任用戶(hù)身份。
  • 令牌(Token): 由IdP頒發(fā), 包含有關(guān)用戶(hù)身份的信息, 以及可能的授權(quán)信息。
  • 單一登錄會(huì)話(huà)(Single Sign-On Session): 用戶(hù)只需一次登錄到IdP,然后就可以訪(fǎng)問(wèn)所有與IdP集成的SP, 而無(wú)需再次提供用戶(hù)名和密碼。

原理圖如下:

圖片

2.JWT原理

JWT 是一種基于 JSON 格式的輕量級(jí)令牌,其主要原理是通過(guò)在服務(wù)端生成一個(gè)包含用戶(hù)信息的 JSON 對(duì)象,然后使用密鑰對(duì)該對(duì)象進(jìn)行簽名,生成一個(gè)令牌。這個(gè)令牌可以被發(fā)送到客戶(hù)端,客戶(hù)端可以在之后的請(qǐng)求中攜帶該令牌,服務(wù)端使用密鑰驗(yàn)證令牌的簽名,并解析其中的信息, 從而完成身份驗(yàn)證。

JWT 由三部分組成:Header(頭部)、Payload(負(fù)載)和 Signature(簽名)。

  • Header(頭部):包含了兩部分信息,token 的類(lèi)型(JWT)和使用的簽名算法,通常是 Base64 編碼的 JSON 字符串。
  • Payload(負(fù)載):包含了一些聲明(Claim),其中包括標(biāo)準(zhǔn)聲明、私有聲明等。這部分也是 Base64 編碼的 JSON 字符串,用于攜帶一些關(guān)鍵的信息。
  • Signature(簽名):由前兩部分使用指定的算法簽名而成,用于驗(yàn)證消息的完整性。

JWT原理圖如下:

圖片

3.使用Golang模擬實(shí)現(xiàn)過(guò)程

為了模擬單點(diǎn)登錄(SSO), 將創(chuàng)建兩個(gè)簡(jiǎn)單的Golang服務(wù): 一個(gè)用于認(rèn)證用戶(hù)(認(rèn)證中心), 另一個(gè)用于資源提供。用戶(hù)如果要獲取資源,必須先登錄認(rèn)證中心獲取令牌, 然后再通過(guò)令牌訪(fǎng)問(wèn)資源服務(wù)器, 下面是認(rèn)證中心的服務(wù)端實(shí)現(xiàn)代碼:

package main

import (
  "fmt"
  "net/http"
  "time"

  "github.com/dgrijalva/jwt-go"
)

var secretKey = []byte("btk.gqv7jtu7VZD1dar")

func main() {
  http.HandleFunc("/login", handleLogin)
  http.ListenAndServe(":8080", nil)
}

func handleLogin(w http.ResponseWriter, r *http.Request) {
  // 在實(shí)際應(yīng)用中,這里應(yīng)該有用戶(hù)認(rèn)證的邏輯,為了簡(jiǎn)化,這里直接使用一個(gè)固定用戶(hù)
  userID := "9527"
  tokenString, err := createToken(userID)
  if err != nil {
    http.Error(w, "創(chuàng)建令牌失敗", http.StatusInternalServerError)
    return
  }

  // 將 JWT 令牌附加到響應(yīng)中
  w.Header().Set("Authorization", "Bearer "+tokenString)
  w.WriteHeader(http.StatusOK)
  fmt.Fprintf(w, "登錄成功. Token: %s", tokenString)
}

func createToken(userID string) (string, error) {
  // 創(chuàng)建負(fù)載
  payload := jwt.MapClaims{
    "user": userID,
    "exptime": time.Now().Add(time.Minute * 15).Unix(), // 令牌過(guò)期時(shí)間為15分鐘
  }

  // 創(chuàng)建 Token
  token := jwt.NewWithClaims(jwt.SigningMethodHS256, payload)

  // 簽名并獲取完整的 Token 字符串
  tokenString, err := token.SignedString(secretKey)
  if err != nil {
    return "", err
  }

  return tokenString, nil
}

在上面的代碼中, 認(rèn)證中心服務(wù)端在本地監(jiān)聽(tīng)8080端口, 用來(lái)模擬處理用戶(hù)的登錄請(qǐng)求, 在收到用戶(hù)請(qǐng)求之后, 服務(wù)端根據(jù)用戶(hù)ID調(diào)用JWT的方法生成Token, 并將Token設(shè)置到HTTP頭的Authorization字段中返回給客戶(hù)端。

接下來(lái)實(shí)現(xiàn)資源提供的服務(wù)端,參考代碼如下:

package main

import (
  "fmt"
  "net/http"

  "github.com/dgrijalva/jwt-go"
)

var secretKey = []byte("btk.gqv7jtu7VZD1dar")

func main() {
  http.HandleFunc("/resource", handleResource)
  http.ListenAndServe(":8081", nil)
}

func handleResource(w http.ResponseWriter, r *http.Request) {
  // 從請(qǐng)求中獲取 Authorization 頭
  authHeader := r.Header.Get("Authorization")
  if authHeader == "" {
    http.Error(w, "未找到Authorization字段", http.StatusUnauthorized)
    return
  }

  // 解析JWT令牌
  tokenString := authHeader[len("Bearer "):]
  token, err := parseToken(tokenString)
  if err != nil || !token.Valid {
    http.Error(w, "令牌不合法", http.StatusUnauthorized)
    return
  }

  // 獲取負(fù)載信息
  claims, ok := token.Claims.(jwt.MapClaims)
  if !ok {
    http.Error(w, "令牌不合法", http.StatusUnauthorized)
    return
  }

  userID, ok := claims["user"].(string)
  if !ok {
    http.Error(w, "訪(fǎng)問(wèn)令牌中的用戶(hù)不存在", http.StatusUnauthorized)
    return
  }

  // 在實(shí)際應(yīng)用中,這里可以根據(jù) userID 獲取用戶(hù)信息或提供資源
  // 這里只是一個(gè)簡(jiǎn)單的示例
  response := fmt.Sprintf("用戶(hù)ID%s獲取資源成功!", userID)
  w.WriteHeader(http.StatusOK)
  fmt.Fprintf(w, response)
}

func parseToken(tokenString string) (*jwt.Token, error) {
  // 解析 Token 字符串
  token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
    return secretKey, nil
  })

  if err != nil {
    return nil, err
  }

  return token, nil
}

在上面的代碼中, 資源服務(wù)端監(jiān)聽(tīng)本地的8081端口, 當(dāng)接收到用戶(hù)請(qǐng)求之后, 首先從請(qǐng)求頭中的Authorization字段獲取Token令牌, 并對(duì)令牌進(jìn)行解析, 如果正確解析出用戶(hù)ID, 返回該用戶(hù)的資源信息。

4.驗(yàn)證實(shí)現(xiàn)結(jié)果

將上面兩段代碼分別編譯成兩個(gè)獨(dú)立Server端,并開(kāi)啟兩個(gè)窗口分別運(yùn)行。首先請(qǐng)求SSO服務(wù)端, 返回結(jié)果如下:

圖片

從上圖可知,SSO服務(wù)端成功返回了一個(gè)Token令牌, 下面先不用Token訪(fǎng)問(wèn)一下資源服務(wù)器試試:

圖片

從上圖可以看到,沒(méi)有令牌無(wú)法正常請(qǐng)求到所需資源, 下面使用Apifox新建一個(gè)請(qǐng)求, 在里面加上Token, 如圖:

圖片

保存之后, 帶著Token請(qǐng)求一下資源服務(wù)端, 如圖:

圖片

可以看到, 成功返回了資源, 整個(gè)流程測(cè)試成功。


網(wǎng)站標(biāo)題:用Go模擬實(shí)現(xiàn)單點(diǎn)登錄Token生成和驗(yàn)證解析
當(dāng)前URL:http://www.5511xx.com/article/coggjph.html