Golang - OAuth2.0使用 - fasthttp版本

OAuth2.0在golang下的使用

一、簡介

1、OAuth2.0使用https來做安全保護,避免了OAuth1.0的複雜加密,讓開發人員更容易使用。
2、接入的四種模式,一般採用授權碼模式,比較安全,其次是密碼模式,不建議使用,其他2種更不推薦。

二、接入流程

授權碼流程圖

  • 1、客戶端可以是手機app,也可以是web瀏覽器,開始請求自己的服務端。
  • 2、服務端發現沒有登陸,則重定向跳轉到認證服務器。
  • 3、認證服務器展示授權頁面,等待用戶手動確認授權。
  • 4、用戶點擊確認後,授權頁面請求認證服務器,獲取授權碼
  • 5、客戶端獲取上一步返回的授權碼。
  • 6、客戶端將授權碼上報給自己的服務端。
  • 7、服務端拿着授權碼去認證服務器換取access_token。
  • 8、服務端通過access_token去認證服務器獲取用戶資料,如openid,用戶暱稱,性別等信息。
三、使用golang開發oauth2服務端

1、導入fasthttp版本的oauth2三方工具包

go get -u github.com/wyanlord/oauth2

2、先看一個示例代碼

package main

import (
	"github.com/dgrijalva/jwt-go"
	"github.com/wyanlord/oauth2/generates"
	"github.com/wyanlord/oauth2/server"
	"github.com/wyanlord/oauth2/store"
	"github.com/wyanlord/oauth2/manage"
	"github.com/wyanlord/oauth2/errors"
	"github.com/wyanlord/oauth2/models"
	"github.com/valyala/fasthttp"
	"log"
)

func main() {
	manager := manage.NewDefaultManager()
	manager.SetAuthorizeCodeTokenCfg(manage.DefaultAuthorizeCodeTokenCfg)

	// token store
	manager.MustTokenStorage(store.NewMemoryTokenStore())

	// generate jwt access token
	manager.MapAccessGenerate(generates.NewJWTAccessGenerate([]byte("00000000"), jwt.SigningMethodHS512))

	clientStore := store.NewClientStore()
	_ = clientStore.Set("222222", &models.Client{
		ID:     "222222",
		Secret: "22222222",
		Domain: "http://localhost:9094",
	})
	manager.MapClientStorage(clientStore)

	srv := server.NewServer(server.NewConfig(), manager)

	srv.SetClientInfoHandler(server.ClientFormHandler)

	srv.SetPasswordAuthorizationHandler(func(username, password string) (userID string, err error) {
		if username == "test" && password == "test" {
			return "123456", nil
		}

		return "", errors.ErrAccessDenied
	})

	srv.SetUserAuthorizationHandler(func(ctx *fasthttp.RequestCtx) (userID string, err error) {
		// 根據您的項目登錄權限的方式來判斷用戶的身份,獲取用戶的id
		return "123456", nil
	})

	srv.SetInternalErrorHandler(func(err error) (re *errors.Response) {
		log.Println("Internal Error:", err.Error())
		return
	})

	srv.SetResponseErrorHandler(func(re *errors.Response) {
		log.Println("Response Error:", re.Error.Error())
	})

	h := fasthttp.CompressHandler(func(ctx *fasthttp.RequestCtx) {
		switch string(ctx.Path()) {
		case "/authorize":
			err := srv.HandleAuthorizeRequest(ctx)
			if err != nil {
				ctx.SetStatusCode(fasthttp.StatusBadRequest)
				_, _ = ctx.WriteString(err.Error())
			}
		case "/token":
			_ = srv.HandleTokenRequest(ctx)
		default:
			ctx.SetStatusCode(fasthttp.StatusNotFound)
		}
	})

	log.Fatal(fasthttp.ListenAndServe(":9096", h))
}

3、示例代碼講解

  • 創建一個默認的管理器manage,用來管理授權碼code和access_token的創建方式和存取方式,以及client_id和client_secret的存取方式。
  • 臨時創建了一個client_id爲222222,client_secret爲22222222,跳轉地址爲http://localhost:9094的三方應用。
  • 設置三方應用上報client_id和client_secret的方式,是通過basic auth方式還是url參數方式。
  • 設置獲取用戶ID的方式。
  • 定義了2個函數,/authorize用來獲取授權碼, /token用來交換access_token。

4、請求示例

  • 獲取授權碼的地址:http://localhost:9096/authorize?client_id=222222&redirect_uri=http%3A%2F%2Flocalhost%3A9094&response_type=code
  • 請在上述的請求頭或者路由裏帶上認證服務器信任的用戶登錄憑證,因爲用戶必須是登錄狀態,才能去認證服務器獲取到攜帶用戶ID的授權碼。
  • 交換access_token的地址:http://localhost:9096/token?client_id=222222&client_secret=22222222&grant_type=authorization_code&redirect_uri=http%3A%2F%2Flocalhost%3A9094&code=SDUF7-HFNXON8V809VVMZW
  • 最終獲取的access_token格式如下:
{
    "access_token": "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiIyMjIyMjIiLCJleHAiOjE1NzQ1MzA5OTIsInN1YiI6IjEyMzQ1NiJ9.CTwRImAbgIi82_hrfrhLRzkyzepxtTm-NrI9FaiiOUOFLbey2YYXMywMjPQS6KyTckhOIvctQAdeH48rsJ9HPg",
    "expires_in": 7200,
    "refresh_token": "JUBVTTJQX5S4SEF2LFASHQ",
    "token_type": "Bearer"
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章