https://github.com/ericchiang/oidc
OpenID Connect support for golang.org/x/oauth2
https://github.com/ericchiang/oidc
Last synced: 12 months ago
JSON representation
OpenID Connect support for golang.org/x/oauth2
- Host: GitHub
- URL: https://github.com/ericchiang/oidc
- Owner: ericchiang
- License: apache-2.0
- Created: 2016-03-03T06:50:28.000Z (over 10 years ago)
- Default Branch: master
- Last Pushed: 2016-09-08T14:33:38.000Z (almost 10 years ago)
- Last Synced: 2025-04-11T12:54:16.312Z (about 1 year ago)
- Language: Go
- Homepage:
- Size: 53.7 KB
- Stars: 13
- Watchers: 2
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# OpenID Connect client support for Go
[](https://godoc.org/github.com/ericchiang/oidc)
This package implements OpenID Connect client logic for the golang.org/x/oauth2 package.
```go
provider, err := oidc.NewProvider(ctx, "https://accounts.example.com")
if err != nil {
return err
}
// Configure an OpenID Connect aware OAuth2 client.
oauth2Config := oauth2.Config{
ClientID: clientID,
ClientSecret: clientSecret,
RedirectURL: redirectURL,
Endpoint: provider.Endpoint(),
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
}
```
OAuth2 redirects are unchanged.
```go
func handleRedirect(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, oauth2Config.AuthCodeURL(state), http.StatusFound)
})
```
For callbacks the provider can be used to query for [user information](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo) such as email.
```go
func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
// Verify state...
oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
return
}
userinfo, err := provider.UserInfo(ctx, oauth2.StaticTokenSource(oauth2Token))
if err != nil {
http.Error(w, "Failed to get userinfo: "+err.Error(), http.StatusInternalServerError)
return
}
// ...
})
```
Or the provider can be used to verify and inspect the OpenID Connect
[ID Token](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) in the
[token response](https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse).
```go
verifier := provider.NewVerifier(ctx)
```
The verifier itself can be constructed with addition checks, such as verifing a
token was issued for a specific client or hasn't expired.
```go
verifier := provier.NewVerifier(ctx, oidc.VerifyAudience(clientID), oidc.VerifyExpiry())
```
The returned verifier can be used to ensure the ID Token (a JWT) is signed by the provider.
```go
func handleOAuth2Callback(w http.ResponseWriter, r *http.Request) {
// Verify state...
oauth2Token, err := oauth2Config.Exchange(ctx, r.URL.Query().Get("code"))
if err != nil {
http.Error(w, "Failed to exchange token: "+err.Error(), http.StatusInternalServerError)
return
}
// Extract the ID Token from oauth2 token.
rawIDToken, ok := oauth2Token.Extra("id_token").(string)
if !ok {
http.Error(w, "No ID Token found", http.StatusInternalServerError)
return
}
// Verify that the ID Token is signed by the provider.
idToken, err := verifier.Verify(rawIDToken)
if err != nil {
http.Error(w, "Failed to verify ID Token: "+err.Error(), http.StatusInternalServerError)
return
}
// Unmarshal ID Token for expected custom claims.
var claims struct {
Email string `json:"email"`
EmailVerified bool `json:"email_verified"`
}
if err := idToken.Claims(&claims); err != nil {
http.Error(w, "Failed to unmarshal ID Token claims: "+err.Error(), http.StatusInternalServerError)
return
}
// ...
})
```