У меня есть токен OAuth 2.0 с пользовательскими свойствами, которые я хочу маршалировать и демаршировать между JSON и golang.org/x/oauth2.Token
struct:
https://godoc.org/golang.org/x/oauth2#Token
Я могу загрузить пользовательские свойства в Token
, используя WithExtra()
, но не могу перенести маркер обратно в JSON представление со всеми пользовательскими свойствами.
Вот что я пробовал.
Используя пример токена OAuth 2.0 с пользовательскими свойствами от Apigee :
{
"issued_at" : "1372170159093",
"application_name" : "ccd1803b-b557-4520-bd62-ddd3abf8e501",
"scope" : "READ",
"status" : "approved",
"api_product_list" : "[Product1,Product2]",
"api_product_list_json" : ["Product1", "Product2"],
"expires_in" : "3599", //--in seconds
"developer.email" : "joe@weathersample.com",
"organization_id" : "0",
"refresh_token" : "82XMXgDyHTpFyXOaApj8C2AGIPnN2IZe",
"client_id" : "deAVedE0W9Z9U35PAMaAJYphBJCGdrND",
"access_token" : "shTUmeI1geSKin0TODcGLXBNe9vp",
"organization_name" : "apifactory",
"refresh_count" : "0"
}
Мне нужно было бы загрузить данные дважды в структуру Token
, один раз, с a json.Unmarshal
и секундная загрузка map[string]interface{}
с использованием WithExtra()
.
- Использование только
WithExtra
не приведет к загрузке стандартных свойств - Использование только
json.Unmarshal(data, token)
не загружает пользовательские свойства
Примечание: код может быть спарен с одним json.Unmarshal
, но я оставил оба, потому что его легче читать.
Вот код:
package main
import(
"encoding/json"
"fmt"
"log"
"golang.org/x/oauth2"
)
const rawToken = `{
"issued_at" : "1372170159093",
"application_name" : "ccd1803b-b557-4520-bd62-ddd3abf8e501",
"scope" : "READ",
"status" : "approved",
"api_product_list" : "[Product1,Product2]",
"api_product_list_json" : ["Product1", "Product2"],
"expires_in" : "3599",
"developer.email" : "joe@weathersample.com",
"organization_id" : "0",
"refresh_token" : "82XMXgDyHTpFyXOaApj8C2AGIPnN2IZe",
"client_id" : "deAVedE0W9Z9U35PAMaAJYphBJCGdrND",
"access_token" : "shTUmeI1geSKin0TODcGLXBNe9vp",
"organization_name" : "apifactory",
"refresh_count" : "0"
}`
func ParseToken(rawToken []byte) (*oauth2.Token, error) {
tok := &oauth2.Token{}
err := json.Unmarshal(rawToken, tok)
if err != nil {
return tok, err
}
msi := map[string]interface{}{}
err = json.Unmarshal(rawToken, &msi)
if err != nil {
return tok, err
}
return tok.WithExtra(msi), nil
}
func main() {
tok, err := ParseToken([]byte(rawToken))
if err != nil {
log.Fatal(err)
}
fmt.Printf("application_name [%s]", tok.Extra("application_name").(string))
}
При таком подходе, если я перенаправлю маркер на JSON, я получу только access_token
, refresh_token
a nd expiry
свойства. Стандартные свойства OAuth 2.0 , такие как scope
и пользовательские свойства не включены.
Я предпочитаю, чтобы это было сделано со структурой oauth2.Token
, чтобы токен мог быть создан с помощью oauth.Config
например, с использованием функции oauth2.Config.Exchange()
. В противном случае может потребоваться новый пакет OAuth 2.0. Некоторые библиотеки, которые я могу использовать для обработки пользовательских данных, включают github.com/dgrijalva/jwt-go
для JWT и github.com/getkin/kin-openapi
для спецификаций OpenAPI.
Вопросы:
- Есть ли более простой способ маршалировать JSON токен в
oauth2.Token
? - Как только пользовательские свойства загружены в
oauth2.Token
, есть ли способ вернуть его обратно в JSON с помощью пользовательские свойства? - Я сейчас использую
golang.org/x/oauth2
, но есть ли еще одна библиотека OAuth 2, которая имеет больше возможностей для обработки пользовательских свойств?