added saving and refreshing token
This commit is contained in:
@@ -3,6 +3,7 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"adam-french.co.uk/backend/services"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/zmb3/spotify/v2"
|
"github.com/zmb3/spotify/v2"
|
||||||
)
|
)
|
||||||
@@ -17,7 +18,7 @@ func (store *Store) CompleteAuth(c *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
store.SpotifyToken = token
|
services.SaveSpotifyToken(services.SPOTIFY_TOKEN_JSON_PATH, token)
|
||||||
|
|
||||||
client := spotify.New(store.SpotifyAuth.Client(c.Request.Context(), token))
|
client := spotify.New(store.SpotifyAuth.Client(c.Request.Context(), token))
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,11 @@ package handlers
|
|||||||
import (
|
import (
|
||||||
"github.com/zmb3/spotify/v2"
|
"github.com/zmb3/spotify/v2"
|
||||||
spotifyauth "github.com/zmb3/spotify/v2/auth"
|
spotifyauth "github.com/zmb3/spotify/v2/auth"
|
||||||
"golang.org/x/oauth2"
|
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Store struct {
|
type Store struct {
|
||||||
DB *gorm.DB
|
DB *gorm.DB
|
||||||
SpotifyAuth *spotifyauth.Authenticator
|
SpotifyAuth *spotifyauth.Authenticator
|
||||||
SpotifyToken *oauth2.Token
|
|
||||||
SpotifyClient *spotify.Client
|
SpotifyClient *spotify.Client
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package services
|
package services
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zmb3/spotify/v2"
|
||||||
spotifyauth "github.com/zmb3/spotify/v2/auth"
|
spotifyauth "github.com/zmb3/spotify/v2/auth"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SpotifyConfig struct {
|
type SpotifyConfig struct {
|
||||||
@@ -13,7 +19,58 @@ type SpotifyConfig struct {
|
|||||||
ClientSecret string
|
ClientSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitSpotifyAuth(config SpotifyConfig) *spotifyauth.Authenticator {
|
const SPOTIFY_TOKEN_JSON_PATH = "spotify_token.json"
|
||||||
|
|
||||||
|
func SaveSpotifyToken(path string, tok *oauth2.Token) error {
|
||||||
|
data := struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
Expiry time.Time `json:"expiry"`
|
||||||
|
}{
|
||||||
|
AccessToken: tok.AccessToken,
|
||||||
|
RefreshToken: tok.RefreshToken,
|
||||||
|
TokenType: tok.TokenType,
|
||||||
|
Expiry: tok.Expiry,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonBytes, err := json.MarshalIndent(data, "", " ")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0600 ensures only your user can read/write the file
|
||||||
|
return os.WriteFile(path, jsonBytes, 0600)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadSpotifyToken(path string) (*oauth2.Token, error) {
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var saved struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
Expiry time.Time `json:"expiry"`
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := json.Unmarshal(data, &saved); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tok := &oauth2.Token{
|
||||||
|
AccessToken: saved.AccessToken,
|
||||||
|
RefreshToken: saved.RefreshToken,
|
||||||
|
TokenType: saved.TokenType,
|
||||||
|
Expiry: saved.Expiry,
|
||||||
|
}
|
||||||
|
|
||||||
|
return tok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitSpotifyAuth(config SpotifyConfig) (*spotifyauth.Authenticator, *spotify.Client) {
|
||||||
auth := spotifyauth.New(
|
auth := spotifyauth.New(
|
||||||
spotifyauth.WithRedirectURL(config.RedirectURL),
|
spotifyauth.WithRedirectURL(config.RedirectURL),
|
||||||
spotifyauth.WithClientID(config.ClientID),
|
spotifyauth.WithClientID(config.ClientID),
|
||||||
@@ -24,8 +81,34 @@ func InitSpotifyAuth(config SpotifyConfig) *spotifyauth.Authenticator {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
fmt.Println("Authenticate spotify with:")
|
// check if token exists locally
|
||||||
|
token, err := LoadSpotifyToken(SPOTIFY_TOKEN_JSON_PATH)
|
||||||
|
if err != nil || token == nil {
|
||||||
|
fmt.Println("No token saved. Authenticate Spotify with:")
|
||||||
fmt.Println(auth.AuthURL(config.AuthState))
|
fmt.Println(auth.AuthURL(config.AuthState))
|
||||||
|
return auth, nil
|
||||||
|
}
|
||||||
|
|
||||||
return auth
|
// refresh token and client
|
||||||
|
client, err := RefreshClient(auth, token)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Failed to refresh token. Authenticate Spotify with:")
|
||||||
|
fmt.Println(auth.AuthURL(config.AuthState))
|
||||||
|
return auth, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return auth, client
|
||||||
|
}
|
||||||
|
|
||||||
|
func RefreshClient(auth *spotifyauth.Authenticator, token *oauth2.Token) (*spotify.Client, error) {
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
token, err := auth.RefreshToken(ctx, token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
client := spotify.New(auth.Client(ctx, token))
|
||||||
|
|
||||||
|
return client, nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user