最小構成 OP
OP を起動する最短経路です。WithIssuer、WithStore、WithKeyset のいずれかを欠くと op.New は error を返します。WithCookieKeys も、authorization_code grant を有効にしている場合は必須です。既定の grant 集合(authorization_code と refresh_token)はこれを含むため、この最小構成では実質的に 4 つとも必須になります。
go
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"log"
"net/http"
"github.com/libraz/go-oidc-provider/op"
"github.com/libraz/go-oidc-provider/op/storeadapter/inmem"
)
func main() {
// 揮発性 ECDSA P-256 (ES256) — 本番では Vault / KMS の鍵に差し替えてください。
// Keyset は {KeyID, Signer} のスライスです。
priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
cookieKey := make([]byte, 32) // AES-256-GCM
if _, err := rand.Read(cookieKey); err != nil {
log.Fatal(err)
}
handler, err := op.New(
op.WithIssuer("https://op.example.com"),
op.WithStore(inmem.New()),
op.WithKeyset(op.Keyset{{KeyID: "k1", Signer: priv}}),
op.WithCookieKeys(cookieKey),
)
if err != nil {
log.Fatal(err)
}
log.Fatal(http.ListenAndServe(":8080", handler))
}go
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"log"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/libraz/go-oidc-provider/op"
"github.com/libraz/go-oidc-provider/op/storeadapter/inmem"
)
func main() {
priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
cookieKey := make([]byte, 32)
if _, err := rand.Read(cookieKey); err != nil {
log.Fatal(err)
}
handler, err := op.New(
op.WithIssuer("https://op.example.com"),
op.WithStore(inmem.New()),
op.WithKeyset(op.Keyset{{KeyID: "k1", Signer: priv}}),
op.WithCookieKeys(cookieKey),
)
if err != nil {
log.Fatal(err)
}
r := chi.NewRouter()
r.Mount("/", handler)
log.Fatal(http.ListenAndServe(":8080", r))
}go
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"log"
"net/http"
"github.com/gin-gonic/gin"
"github.com/libraz/go-oidc-provider/op"
"github.com/libraz/go-oidc-provider/op/storeadapter/inmem"
)
func main() {
priv, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
cookieKey := make([]byte, 32)
if _, err := rand.Read(cookieKey); err != nil {
log.Fatal(err)
}
handler, err := op.New(
op.WithIssuer("https://op.example.com"),
op.WithStore(inmem.New()),
op.WithKeyset(op.Keyset{{KeyID: "k1", Signer: priv}}),
op.WithCookieKeys(cookieKey),
)
if err != nil {
log.Fatal(err)
}
r := gin.New()
r.Any("/*path", gin.WrapH(handler))
log.Fatal(http.ListenAndServe(":8080", r))
}本番運用の注意
- 鍵: ここでは揮発性ですが、本番では Vault / KMS から読み込むこと。
- ストア: in-memory ですが、本番では
op/storeadapter/sqlかcompositeを使うこと。 - リスナ: 平文 HTTP のままです。TLS 終端 ingress の背後に置いてください。
この OP で今すぐ試せること
curl http://localhost:8080/.well-known/openid-configuration— discovery。mount prefix に関わらず常にルート直下に公開されます。curl http://localhost:8080/oidc/jwks— ID トークン検証用の公開 JWKS。- 既定の mount prefix は
/oidcです。op.WithMountPrefix("/")で変更できます。 - クライアントと authenticator を登録するまで認可は error を返します。
upstream 例の実行
sh
git clone https://github.com/libraz/go-oidc-provider.git
cd go-oidc-provider
(cd examples/01-minimal && go run -tags example .)upstream の 01-minimal 例では examples/internal/devkeys が揮発性鍵を、examples/internal/serve がリスナまわりの定型コードを提供します。そのため、main.go 自体は op.New に集中できます。
次へ
- 必須オプション — 常時必須の項目と、CookieKeys が必要になる条件。
- ルーターへの組み込み —
chi、gin… - 使い方: 最小構成 OP — クライアント登録と authenticator を組み込んだ同じ例。