You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请求帮助:为Spotify艺人信息查询代码添加自动刷新Token功能

Implementing Spotify Token Auto-Refresh in ASP.NET Web Forms

Got it, let's tackle this Spotify token auto-refresh issue in your ASP.NET Web Forms project. The key here is leveraging Spotify's refresh token, which lets you get a new access token without requiring the user to re-authenticate every hour. Here's a step-by-step implementation tailored to your aspx/aspx.cs setup:

1. Make Sure You Request the offline_access Scope First

This is non-negotiable—Spotify only issues a refresh token if your initial authorization request includes the offline_access scope. Update your authorization redirect URL to include it:

// In your authorization page's code-behind (e.g., AuthorizeSpotify.aspx.cs)
protected void Page_Load(object sender, EventArgs e)
{
    string clientId = ConfigurationManager.AppSettings["SpotifyClientId"];
    string redirectUri = ConfigurationManager.AppSettings["SpotifyRedirectUri"];
    // Include offline_access in the scope list
    string scope = "user-read-private user-read-email offline_access"; // Add any other scopes you need

    string authUrl = $"https://accounts.spotify.com/authorize?client_id={clientId}&response_type=code&redirect_uri={Uri.EscapeDataString(redirectUri)}&scope={Uri.EscapeDataString(scope)}";
    Response.Redirect(authUrl);
}

2. Store the Refresh Token and Token Expiry Date

When you first exchange the authorization code for an access token, Spotify will return a refresh token. Store this securely (along with the access token and its expiry time) — you can use Session for single-user scenarios, or a database for multi-user apps.

First, define a model to parse the token response:

// Add this class to your project (e.g., in a Models folder)
public class SpotifyTokenResponse
{
    [JsonPropertyName("access_token")]
    public string AccessToken { get; set; }

    [JsonPropertyName("token_type")]
    public string TokenType { get; set; }

    [JsonPropertyName("expires_in")]
    public int ExpiresIn { get; set; }

    [JsonPropertyName("refresh_token")]
    public string RefreshToken { get; set; }

    [JsonPropertyName("scope")]
    public string Scope { get; set; }
}

Then, in your redirect callback page (where you exchange the code for tokens):

// In your callback page's code-behind (e.g., SpotifyCallback.aspx.cs)
protected async void Page_Load(object sender, EventArgs e)
{
    string code = Request.QueryString["code"];
    if (string.IsNullOrEmpty(code)) return;

    string clientId = ConfigurationManager.AppSettings["SpotifyClientId"];
    string clientSecret = ConfigurationManager.AppSettings["SpotifyClientSecret"];
    string redirectUri = ConfigurationManager.AppSettings["SpotifyRedirectUri"];

    using (var client = new HttpClient())
    {
        var formData = new Dictionary<string, string>
        {
            ["grant_type"] = "authorization_code",
            ["code"] = code,
            ["redirect_uri"] = redirectUri,
            ["client_id"] = clientId,
            ["client_secret"] = clientSecret
        };

        var response = await client.PostAsync("https://accounts.spotify.com/api/token", new FormUrlEncodedContent(formData));
        response.EnsureSuccessStatusCode();

        var tokenData = await response.Content.ReadFromJsonAsync<SpotifyTokenResponse>();

        // Store tokens in Session (adjust for database if needed)
        Session["SpotifyAccessToken"] = tokenData.AccessToken;
        Session["SpotifyRefreshToken"] = tokenData.RefreshToken;
        // Calculate expiry time (add expires_in seconds to current time)
        Session["SpotifyTokenExpiresAt"] = DateTime.Now.AddSeconds(tokenData.ExpiresIn);

        // Redirect back to your search page
        Response.Redirect("~/SpotifySearch.aspx");
    }
}

3. Add a Method to Refresh the Access Token

Create a reusable method that uses the stored refresh token to get a new access token. This will run automatically when the current token is about to expire.

// In your search page's code-behind (e.g., SpotifySearch.aspx.cs)
private async Task RefreshAccessToken()
{
    string refreshToken = Session["SpotifyRefreshToken"] as string;
    if (string.IsNullOrEmpty(refreshToken))
    {
        // No refresh token available—redirect to re-authorize
        Response.Redirect("~/AuthorizeSpotify.aspx");
        return;
    }

    string clientId = ConfigurationManager.AppSettings["SpotifyClientId"];
    string clientSecret = ConfigurationManager.AppSettings["SpotifyClientSecret"];

    using (var client = new HttpClient())
    {
        var formData = new Dictionary<string, string>
        {
            ["grant_type"] = "refresh_token",
            ["refresh_token"] = refreshToken,
            ["client_id"] = clientId,
            ["client_secret"] = clientSecret
        };

        var response = await client.PostAsync("https://accounts.spotify.com/api/token", new FormUrlEncodedContent(formData));
        if (!response.IsSuccessStatusCode)
        {
            // Refresh failed (e.g., token revoked)—redirect to re-authorize
            Response.Redirect("~/AuthorizeSpotify.aspx");
            return;
        }

        var tokenData = await response.Content.ReadFromJsonAsync<SpotifyTokenResponse>();

        // Update stored tokens
        Session["SpotifyAccessToken"] = tokenData.AccessToken;
        // Spotify may return a new refresh token—update it if provided
        if (!string.IsNullOrEmpty(tokenData.RefreshToken))
        {
            Session["SpotifyRefreshToken"] = tokenData.RefreshToken;
        }
        Session["SpotifyTokenExpiresAt"] = DateTime.Now.AddSeconds(tokenData.ExpiresIn);
    }
}

4. Check Token Validity Before Calling Spotify API

Add a helper method to check if the current token is still valid (or about to expire) and refresh it if needed. Call this method before any Spotify API request.

// In SpotifySearch.aspx.cs
private async Task EnsureValidToken()
{
    DateTime? expiresAt = Session["SpotifyTokenExpiresAt"] as DateTime?;
    // Refresh token 5 minutes before it expires to avoid race conditions
    if (!expiresAt.HasValue || DateTime.Now >= expiresAt.Value.AddMinutes(-5))
    {
        await RefreshAccessToken();
    }
}

// Example method to fetch artist info (your existing search functionality)
public async Task<string> GetArtistInfo(string artistName)
{
    await EnsureValidToken();
    string accessToken = Session["SpotifyAccessToken"] as string;

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
        var response = await client.GetAsync($"https://api.spotify.com/v1/search?q={Uri.EscapeDataString(artistName)}&type=artist");
        response.EnsureSuccessStatusCode();
        return await response.Content.ReadAsStringAsync();
    }
}

Key Notes for Production

  • Secure Storage: Never hardcode your client_id or client_secret—store them in Web.config under <appSettings> or use environment variables.
  • Multi-User Apps: If your app has multiple users, replace Session with a database table that links refresh tokens to user accounts.
  • Error Handling: Add more robust error handling for network failures or token revocation scenarios.
  • Background Refresh: If you need to refresh tokens even when the user isn't active, consider using a background service (like Hangfire) instead of checking on each request.

内容的提问来源于stack exchange,提问作者James

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:50:39