ホームページ >バックエンド開発 >Golang >golangでssoを実装する方法

golangでssoを実装する方法

PHPz
PHPzオリジナル
2023-04-13 09:11:15750ブラウズ

今日のインターネット時代において、シングル サインオン (SSO) は非常に重要なテクノロジの 1 つになっています。ユーザーのログインが容易になるだけでなく、Web サイトのセキュリティも向上します。近年、その効率性と安定性により、golang は徐々に多くの企業に選ばれる開発言語となり、SSO を実装する開発者からの注目がますます高まっています。次に、golang が SSO を実装する方法を紹介します。

1. SSO とは

SSO (正式名はシングル サインオン) は、複数のアプリケーションが同じ認証システムを共有できるようにするテクノロジを指します。その主な機能は、ユーザーが複数の異なるシステムに 1 回だけログインして、それらのシステムで操作できるようにすることです。これにより、ユーザーの操作が軽減され、作業効率が向上するだけでなく、ユーザーがアカウントとパスワードを忘れるという問題も回避できます。 SSO の最も一般的に使用される実装方法は、トークン認証メカニズムに基づいています。ユーザーが正常にログインすると、サーバーはクライアントにトークンを返します。同時に、トークンはユーザー ID の一意の識別子として使用されます。ユーザーが他のシステムにアクセスするときは、トークンを持ち歩くだけで済みます。

2. Golang で SSO を実装するプロセス

  1. ログイン認証

まず、ユーザーがシステムにアクセスするときに、次のことを実行する必要があります。最初にログイン認証が行われ、システムはユーザーの名前とパスワードが正しいかどうかを確認する必要があります。正しい場合、トークンが生成され、クライアントに返されます。このトークンは一定期間内であれば利用可能ですが、有効期限が切れた場合は再度ログインする必要があります。 golang では、JWT (JSON Web Tokens) を使用してトークンを生成できます。JWT はオープン標準であり、さまざまなシナリオで安全な検証とデータ転送に使用できます。このうち、JWT はヘッダー、ペイロード、署名の 3 つの部分で構成されます。 HeaderやPayloadにはユーザーIDなど任意の情報を格納することができ、その後の検証時の判断材料として利用できます。署名は、トークンの安全性を確保するために、ヘッダーとペイロードの暗号化に基づいて生成される署名です。

  1. トークンの検証

SSO 認証プロセス中に、システムはトークンを検証して、トークンがシステムによって生成され、有効期間内であることを確認する必要があります。検証プロセスは、各システム内で実行することも、専用の認証システムを通じて実行することもできます。 golang では、ミドルウェアを通じてトークンの検証を完了できます。リクエスト ヘッダーのトークンが要件を満たしているかどうかを確認するミドルウェアを定義できます。満たしていない場合はエラー メッセージを返し、満たしている場合は次のステップに進みます。

func AuthMiddleware(次の http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    authHeader := r.Header.Get("Authorization") 
    if authHeader == "" { 
        http.Error(w, "Authorization required", http.StatusUnauthorized) 
        return 
    } 
    token, err := jwt.Parse(authHeader, func(token *jwt.Token) (interface{}, error) { 
        if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { 
            return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) 
        } 
        return []byte("secret"),nil //这里是Token的密钥,可以根据实际需要进行设置 
    }) 
    if err != nil || !token.Valid { 
        http.Error(w, "Invalid token", http.StatusUnauthorized) 
        return 
    } 
    // Token校验通过 
    next.ServeHTTP(w, r) 
})

}

  1. トークン更新

有効期限と合計トークンのリフレッシュは、SSO 認証におけるもう 1 つの非常に重要な要素です。トークンの有効期限が切れるとログイン認証をやり直す必要があり、ユーザーはシステムを頻繁に切り替えることになり、毎回ログインし直す必要があると煩わしいだけでなく、ユーザーエクスペリエンスにも悪影響を及ぼします。 。したがって、トークンの有効期限が近づくと、特別なインターフェイスを通じてトークンを更新し、ユーザーのログイン状態を維持できます。 golang では、トークンの有効期限を設定できます。トークンの有効期限が切れそうになったら、リフレッシュ トークンを使用してトークンを更新すると、ユーザーが再認証する必要がなくなります。

func RefreshToken(w http.ResponseWriter, r *http.Request) {

authHeader := r.Header.Get("Authorization") 
if authHeader == "" { 
    http.Error(w, "Authorization required", http.StatusUnauthorized) 
    return 
} 
token, err := jwt.Parse(authHeader, func(token *jwt.Token) (interface{}, error) { 
    if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { 
        return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) 
    } 
    return []byte("secret"),nil //这里是Token的密钥,可以根据实际需要进行设置 
}) 
if err != nil { 
    http.Error(w, "Invalid token", http.StatusUnauthorized) 
    return 
} 
if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { 
    if time.Unix(int64(claims["exp"].(float64)), 0).Sub(time.Now())/time.Second < RefreshTokenExpired { 
        newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ 
            "user_id": claims["user_id"], 
            "exp": time.Now().Add(time.Hour * 24).Unix(), 
        }) 
        tokenString, _ := newToken.SignedString([]byte("secret")) 
        w.WriteHeader(http.StatusOK) 
        w.Write([]byte(tokenString)) 
        return 
    } 
} 
http.Error(w, "Failed to refresh token", http.StatusUnauthorized)

}

  1. クロスドメイン処理

SSO認証を行う場合、各システム間でToken等の情報をやり取りする必要があるため、クロスドメインの問題を考慮する必要があります。 golang では、ヘッダーを変更することでクロスドメインの問題を解決できます。クロスドメイン ミドルウェアを定義し、対応するヘッダーをリクエストに追加して、クロスドメイン リクエストの問題を解決できます。

func CORSMiddleware(次の http.Handler) http.Handler {

return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
    w.Header().Set("Access-Control-Allow-Origin", "*") 
    w.Header().Set("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS") 
    w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") 
    if r.Method == "OPTIONS" { 
        w.WriteHeader(http.StatusOK) 
        return 
    } 
    next.ServeHTTP(w, r) 
})

}

3. 概要

今日のインターネット時代では、SSO は 1 つになりました。非常に重要な技術のこと。近年、golang は徐々に多くの企業に選ばれる開発言語となり、SSO の実装過程で開発者からの注目がますます高まっています。以上の説明から、golang で SSO を実装することはそれほど難しいことではなく、JWT を通じてトークンを生成し、ミドルウェアを通じてトークン検証とクロスドメイン処理を実行することで SSO 機能を実現できることがわかりました。

以上がgolangでssoを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。