Googleと一緒にOAuth 2
認証は、任意のアプリケーションで最も一般的な部分です.あなた自身の認証システムを実装するか、存在する多くの選択肢のうちの1つを使用することができます、しかし、この場合、我々はOAuS 2を使用するつもりです.
OAuthはOAuth 2 Go hereの詳細については、ユーザーが自分のユーザ名とパスワードをそのサービスで共有することなくデータをアクセスできるようにする仕様です.
まず最初に、Googleプロジェクトを作成し、OAuth 2の資格情報を作成する必要があります.は、Google雲プラットホーム に行きます新しいプロジェクトを作成するか、すでにそれを選択した場合. 資格証明書に行き、次に「OAuthクライアントID」を選択する新しいものを作成します は、この例の
はCententCard IDとクライアント秘密 をコピーします
承認シーケンスは、アプリケーションがブラウザをGoogle URLにリダイレクトするときに開始されますURLには、要求されているアクセスの種類を示すクエリパラメーターが含まれます.Googleはユーザ認証、セッション選択、ユーザー同意を扱います.結果はアプリケーションがアクセストークンとリフレッシュトークンと交換できる認可コードです.
アプリケーションは、将来の使用のためにリフレッシュトークンを保存し、Google APIにアクセスするためのアクセストークンを使用します.アクセストークンが期限切れになると、アプリケーションは新しいトークンを取得するためにリフレッシュトークンを使用します.
OAuth 2認証と認証HTTPリクエストのサポートを提供するパッケージ「Golang . org/X/OAuth 2」を使用します.
あなたのWorddirに新しいプロジェクト(フォルダ)を作成します.私の場合は「oauths 2」と呼びますが、OAutor 2のパッケージを含める必要があります.
次に、このフォルダの「ベース」を作成します.どうぞ.
また、Google Auth\/Auth/Google/login "と"\/auth/Google/callback "でOAuth用の2つのエンドポイントを作成します.我々はGoogleコンソールでアプリケーションを設定するときに覚えていますか?コールバックURLは同じでなければなりません.
次に、ハンドラに別のファイルを作成します.移動してください、このファイルは、我々のアプリケーションでGoogleでOAuthを扱うすべてのロジックを含みます.
VAR GoogleOAuconfigをAuthで宣言します.Googleと通信する設定.
スコープ:OAuth 2.0スコープは、アクセストークンに与えられるアクセス量を制限する方法を提供します.
このハンドラはログインリンクを作成し、ユーザをリダイレクトします.
AuthCodeURL CSRF攻撃からユーザーを保護するためのトークンである状態を受け取ります.常に空の文字列を提供し、リダイレクトコールバックの状態クエリパラメーターと一致することを検証する必要があります.これは、各リクエストに対してランダムに生成されることをお勧めします.
このハンドラは、状態がOAuthEstateCookieに等しいかどうかをチェックし、その関数をGetGetDataFromGoogle関数に渡します.
OAuthはOAuth 2 Go hereの詳細については、ユーザーが自分のユーザ名とパスワードをそのサービスで共有することなくデータをアクセスできるようにする仕様です.
設定プロジェクト
まず最初に、Googleプロジェクトを作成し、OAuth 2の資格情報を作成する必要があります.
localhost:8000/auth/google/callback
のために「認可されたリダイレクトURL」を加えますOAuth 2の使い方
承認シーケンスは、アプリケーションがブラウザをGoogle URLにリダイレクトするときに開始されますURLには、要求されているアクセスの種類を示すクエリパラメーターが含まれます.Googleはユーザ認証、セッション選択、ユーザー同意を扱います.結果はアプリケーションがアクセストークンとリフレッシュトークンと交換できる認可コードです.
アプリケーションは、将来の使用のためにリフレッシュトークンを保存し、Google APIにアクセスするためのアクセストークンを使用します.アクセストークンが期限切れになると、アプリケーションは新しいトークンを取得するためにリフレッシュトークンを使用します.
コードに行こう
OAuth 2認証と認証HTTPリクエストのサポートを提供するパッケージ「Golang . org/X/OAuth 2」を使用します.
あなたのWorddirに新しいプロジェクト(フォルダ)を作成します.私の場合は「oauths 2」と呼びますが、OAutor 2のパッケージを含める必要があります.
go get golang.org/x/oauth2
だからプロジェクトに我々はメインを作成します.行け.package main
import (
"fmt"
"net/http"
"log"
"github.com/douglasmakey/oauth2-example/handlers"
)
func main() {
server := &http.Server{
Addr: fmt.Sprintf(":8000"),
Handler: handlers.New(),
}
log.Printf("Starting HTTP Server. Listening at %q", server.Addr)
if err := server.ListenAndServe(); err != http.ErrServerClosed {
log.Printf("%v", err)
} else {
log.Println("Server closed!")
}
}
HTTPを使用して簡単なサーバーを作成します.サーバーと実行.次に、このフォルダの「ベース」を作成します.どうぞ.
package handlers
import (
"net/http"
)
func New() http.Handler {
mux := http.NewServeMux()
// Root
mux.Handle("/", http.FileServer(http.Dir("templates/")))
// OauthGoogle
mux.HandleFunc("/auth/google/login", oauthGoogleLogin)
mux.HandleFunc("/auth/google/callback", oauthGoogleCallback)
return mux
}
HTTPを使用します.私たちのエンドポイントを処理するためのServemuxは、次のルートエンドポイント“/”を作成します.HTTPこのファイルは' index 'です.HTML 'とフォルダ'テンプレート'です.また、Google Auth\/Auth/Google/login "と"\/auth/Google/callback "でOAuth用の2つのエンドポイントを作成します.我々はGoogleコンソールでアプリケーションを設定するときに覚えていますか?コールバックURLは同じでなければなりません.
次に、ハンドラに別のファイルを作成します.移動してください、このファイルは、我々のアプリケーションでGoogleでOAuthを扱うすべてのロジックを含みます.
VAR GoogleOAuconfigをAuthで宣言します.Googleと通信する設定.
スコープ:OAuth 2.0スコープは、アクセストークンに与えられるアクセス量を制限する方法を提供します.
var googleOauthConfig = &oauth2.Config{
RedirectURL: "http://localhost:8000/auth/google/callback",
ClientID: os.Getenv("GOOGLE_OAUTH_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_OAUTH_CLIENT_SECRET"),
Scopes: []string{"https://www.googleapis.com/auth/userinfo.email"},
Endpoint: google.Endpoint,
}
ハンドラー
このハンドラはログインリンクを作成し、ユーザをリダイレクトします.
AuthCodeURL CSRF攻撃からユーザーを保護するためのトークンである状態を受け取ります.常に空の文字列を提供し、リダイレクトコールバックの状態クエリパラメーターと一致することを検証する必要があります.これは、各リクエストに対してランダムに生成されることをお勧めします.
func oauthGoogleLogin(w http.ResponseWriter, r *http.Request) {
// Create oauthState cookie
oauthState := generateStateOauthCookie(w)
u := googleOauthConfig.AuthCodeURL(oauthState)
http.Redirect(w, r, u, http.StatusTemporaryRedirect)
}
func generateStateOauthCookie(w http.ResponseWriter) string {
var expiration = time.Now().Add(365 * 24 * time.Hour)
b := make([]byte, 16)
rand.Read(b)
state := base64.URLEncoding.EncodeToString(b)
cookie := http.Cookie{Name: "oauthstate", Value: state, Expires: expiration}
http.SetCookie(w, &cookie)
return state
}
ハンドラハンドラ
このハンドラは、状態がOAuthEstateCookieに等しいかどうかをチェックし、その関数をGetGetDataFromGoogle関数に渡します.
func oauthGoogleCallback(w http.ResponseWriter, r *http.Request) {
// Read oauthState from Cookie
oauthState, _ := r.Cookie("oauthstate")
if r.FormValue("state") != oauthState.Value {
log.Println("invalid oauth google state")
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
data, err := getUserDataFromGoogle(r.FormValue("code"))
if err != nil {
log.Println(err.Error())
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
// GetOrCreate User in your db.
// Redirect or response with a token.
// More code .....
fmt.Fprintf(w, "UserInfo: %s\n", data)
}
func getUserDataFromGoogle(code string) ([]byte, error) {
// Use code to get token and get user info from Google.
token, err := googleOauthConfig.Exchange(context.Background(), code)
if err != nil {
return nil, fmt.Errorf("code exchange wrong: %s", err.Error())
}
response, err := http.Get(oauthGoogleUrlAPI + token.AccessToken)
if err != nil {
return nil, fmt.Errorf("failed getting user info: %s", err.Error())
}
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("failed read response: %s", err.Error())
}
return contents, nil
}
完全なコードOAuthMen Google。試み
package handlers
import (
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"net/http"
"fmt"
"io/ioutil"
"context"
"log"
"encoding/base64"
"crypto/rand"
"os"
"time"
)
// Scopes: OAuth 2.0 scopes provide a way to limit the amount of access that is granted to an access token.
var googleOauthConfig = &oauth2.Config{
RedirectURL: "http://localhost:8000/auth/google/callback",
ClientID: os.Getenv("GOOGLE_OAUTH_CLIENT_ID"),
ClientSecret: os.Getenv("GOOGLE_OAUTH_CLIENT_SECRET"),
Scopes: []string{"https://www.googleapis.com/auth/userinfo.email"},
Endpoint: google.Endpoint,
}
const oauthGoogleUrlAPI = "https://www.googleapis.com/oauth2/v2/userinfo?access_token="
func oauthGoogleLogin(w http.ResponseWriter, r *http.Request) {
// Create oauthState cookie
oauthState := generateStateOauthCookie(w)
/*
AuthCodeURL receive state that is a token to protect the user from CSRF attacks. You must always provide a non-empty string and
validate that it matches the the state query parameter on your redirect callback.
*/
u := googleOauthConfig.AuthCodeURL(oauthState)
http.Redirect(w, r, u, http.StatusTemporaryRedirect)
}
func oauthGoogleCallback(w http.ResponseWriter, r *http.Request) {
// Read oauthState from Cookie
oauthState, _ := r.Cookie("oauthstate")
if r.FormValue("state") != oauthState.Value {
log.Println("invalid oauth google state")
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
data, err := getUserDataFromGoogle(r.FormValue("code"))
if err != nil {
log.Println(err.Error())
http.Redirect(w, r, "/", http.StatusTemporaryRedirect)
return
}
// GetOrCreate User in your db.
// Redirect or response with a token.
// More code .....
fmt.Fprintf(w, "UserInfo: %s\n", data)
}
func generateStateOauthCookie(w http.ResponseWriter) string {
var expiration = time.Now().Add(365 * 24 * time.Hour)
b := make([]byte, 16)
rand.Read(b)
state := base64.URLEncoding.EncodeToString(b)
cookie := http.Cookie{Name: "oauthstate", Value: state, Expires: expiration}
http.SetCookie(w, &cookie)
return state
}
func getUserDataFromGoogle(code string) ([]byte, error) {
// Use code to get token and get user info from Google.
token, err := googleOauthConfig.Exchange(context.Background(), code)
if err != nil {
return nil, fmt.Errorf("code exchange wrong: %s", err.Error())
}
response, err := http.Get(oauthGoogleUrlAPI + token.AccessToken)
if err != nil {
return nil, fmt.Errorf("failed getting user info: %s", err.Error())
}
defer response.Body.Close()
contents, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, fmt.Errorf("failed read response: %s", err.Error())
}
return contents, nil
}
走りましょう
go run main.go
コードRepoでのリポジトリReference
この問題について(Googleと一緒にOAuth 2), 我々は、より多くの情報をここで見つけました https://dev.to/douglasmakey/oauth2-example-with-go-3n8aテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol