forked from zmb3/spotify
/
pkce.go
77 lines (67 loc) · 2.62 KB
/
pkce.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// This example demonstrates how to authenticate with Spotify using the authorization code flow with PKCE.
// In order to run this example yourself, you'll need to:
//
// 1. Register an application at: https://developer.spotify.com/my-applications/
// - Use "http://localhost:8080/callback" as the redirect URI
// 2. Set the SPOTIFY_ID environment variable to the client ID you got in step 1.
package main
import (
"context"
"fmt"
spotifyauth "github.com/conradludgate/spotify/v2/auth"
"log"
"net/http"
"golang.org/x/oauth2"
"github.com/conradludgate/spotify/v2"
)
// redirectURI is the OAuth redirect URI for the application.
// You must register an application at Spotify's developer portal
// and enter this value.
const redirectURI = "http://localhost:8080/callback"
var (
auth = spotifyauth.New(spotifyauth.WithRedirectURL(redirectURI), spotifyauth.WithScopes(spotifyauth.ScopeUserReadPrivate))
ch = make(chan *spotify.Client)
state = "abc123"
// These should be randomly generated for each request
// More information on generating these can be found here,
// https://www.oauth.com/playground/authorization-code-with-pkce.html
codeVerifier = "w0HfYrKnG8AihqYHA9_XUPTIcqEXQvCQfOF2IitRgmlF43YWJ8dy2b49ZUwVUOR.YnvzVoTBL57BwIhM4ouSa~tdf0eE_OmiMC_ESCcVOe7maSLIk9IOdBhRstAxjCl7"
codeChallenge = "ZhZJzPQXYBMjH8FlGAdYK5AndohLzFfZT-8J7biT7ig"
)
func main() {
// first start an HTTP server
http.HandleFunc("/callback", completeAuth)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
log.Println("Got request for:", r.URL.String())
})
go http.ListenAndServe(":8080", nil)
url := auth.AuthURL(state,
oauth2.SetAuthURLParam("code_challenge_method", "S256"),
oauth2.SetAuthURLParam("code_challenge", codeChallenge),
)
fmt.Println("Please log in to Spotify by visiting the following page in your browser:", url)
// wait for auth to complete
client := <-ch
// use the client to make calls that require authorization
user, err := client.CurrentUser(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println("You are logged in as:", user.ID)
}
func completeAuth(w http.ResponseWriter, r *http.Request) {
tok, err := auth.Token(r.Context(), state, r,
oauth2.SetAuthURLParam("code_verifier", codeVerifier))
if err != nil {
http.Error(w, "Couldn't get token", http.StatusForbidden)
log.Fatal(err)
}
if st := r.FormValue("state"); st != state {
http.NotFound(w, r)
log.Fatalf("State mismatch: %s != %s\n", st, state)
}
// use the token to get an authenticated client
client := spotify.New(spotify.WithHTTPClient(auth.Client(r.Context(), tok)))
fmt.Fprintf(w, "Login Completed!")
ch <- client
}