Skip to content

Commit b582cc0

Browse files
committed
make PKCE easier
1 parent e07593a commit b582cc0

File tree

2 files changed

+52
-6
lines changed

2 files changed

+52
-6
lines changed

authhandler/authhandler.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,7 @@ const (
2222
codeVerifierKey = "code_verifier"
2323
)
2424

25-
// PKCEParams holds parameters to support PKCE.
26-
type PKCEParams struct {
27-
Challenge string // The unpadded, base64-url-encoded string of the encrypted code verifier.
28-
ChallengeMethod string // The encryption method (ex. S256).
29-
Verifier string // The original, non-encrypted secret.
30-
}
25+
type PKCEParams = oauth2.PKCEParams
3126

3227
// AuthorizationHandler is a 3-legged-OAuth helper that prompts
3328
// the user for OAuth consent at the specified auth code URL

oauth2.go

+51
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@ package oauth2 // import "golang.org/x/oauth2"
1111
import (
1212
"bytes"
1313
"context"
14+
"crypto/rand"
15+
"crypto/sha256"
16+
"encoding/base64"
1417
"errors"
18+
"io"
1519
"net/http"
1620
"net/url"
1721
"strings"
@@ -379,3 +383,50 @@ func ReuseTokenSource(t *Token, src TokenSource) TokenSource {
379383
new: src,
380384
}
381385
}
386+
387+
// PKCEParams holds parameters to support PKCE.
388+
type PKCEParams struct {
389+
Challenge string // The unpadded, base64-url-encoded string of the encrypted code verifier.
390+
ChallengeMethod string // The encryption method (ex. S256).
391+
Verifier string // The original, non-encrypted secret.
392+
}
393+
394+
const (
395+
// Parameter keys for AuthCodeURL method to support PKCE.
396+
codeChallengeKey = "code_challenge"
397+
codeChallengeMethodKey = "code_challenge_method"
398+
399+
// Parameter key for Exchange method to support PKCE.
400+
codeVerifierKey = "code_verifier"
401+
)
402+
403+
func (p *PKCEParams) AuthCodeOptions() []AuthCodeOption {
404+
return []AuthCodeOption{
405+
SetAuthURLParam(codeChallengeKey, p.Challenge),
406+
SetAuthURLParam(codeChallengeMethodKey, p.ChallengeMethod)}
407+
}
408+
409+
func (p *PKCEParams) ExchangeOptions() []AuthCodeOption {
410+
return []AuthCodeOption{
411+
SetAuthURLParam(codeVerifierKey, p.Verifier)}
412+
}
413+
414+
func randomString(n int) string {
415+
data := make([]byte, n)
416+
if _, err := io.ReadFull(rand.Reader, data); err != nil {
417+
panic(err)
418+
}
419+
return base64.StdEncoding.EncodeToString(data)
420+
}
421+
422+
func GeneratePKCEParams() *PKCEParams {
423+
verifier := randomString(32)
424+
sha := sha256.Sum256([]byte(verifier))
425+
challenge := base64.URLEncoding.WithPadding(base64.NoPadding).EncodeToString(sha[:])
426+
427+
return &PKCEParams{
428+
Challenge: challenge,
429+
ChallengeMethod: "S256",
430+
Verifier: verifier,
431+
}
432+
}

0 commit comments

Comments
 (0)