我在哪里存储Web API访问令牌?

时间:2015-02-02 20:57:29

标签: asp.net-mvc asp.net-web-api

我有一个非常瘦的前端ASP.NET MVC 5应用程序,它与WebApi 2后端进行通信。这些是单独的应用程序

我从WebApi获得了身份验证令牌。我必须在用户登录时获取它。我将它存储在会话状态,但这显然是错误的地方。我有用户仍然登录但auth令牌不再在会话中的情况。

我需要将它与我的身份验证cookie一起存储,并且它需要具有相同的生命周期。为什么没有办法开箱即用?我相信这是成千上万程序员面临的情况。

以下是我将其存储到Session中的代码:

/// <summary>
/// Configure the application sign-in manager which is used in this application.
/// </summary>
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public override async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
    {
        var status = await base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout);

        if (status == SignInStatus.Success)
            await PasswordSaveTokenAsync(userName, password);

        return status;
    }

    /// <summary>
    /// Get the token from the Web API with the given user name (<paramref name="userName"/>) and password 
    ///     (<paramref name="password"/>) and save it to the session state.
    /// </summary>
    /// <param name="userName">User name.</param>
    /// <param name="password">Password.</param>
    private async Task PasswordSaveTokenAsync(string userName, string password)
    {
        var baseAddress = Config.WebApiAddress;

        var client = new HttpClient { BaseAddress = baseAddress };
        var response = await client.PostAsync("Token", new StringContent(String.Format("grant_type=password&username={0}&password={1}", userName, password), Encoding.UTF8));

        response.EnsureSuccessStatusCode();

        var tokenResponse = await response.Content.ReadAsStringAsync();
        var json = JObject.Parse(tokenResponse);

        var token = json["access_token"].ToString();

        Session.AccessToken = token;
    }
}

2 个答案:

答案 0 :(得分:0)

这是我提出的解决方案。

在Global.asax中:

public class MvcApplication : System.Web.HttpApplication
{
    // Other members removed for brevity.

    protected void Session_Start()
    {
        var cookie = Request.Cookies["AccessToken"];

        if (cookie != null && cookie.Value != null)
            Session["AccessToken"] = cookie.Value;
    }
}

在ApplicationSignInManager.cs中:

public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    // Comments and other members removed for brevity.

    public override async Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
    {
        var status = await base.PasswordSignInAsync(userName, password, isPersistent, shouldLockout);

        if (status == SignInStatus.Success)
            await PasswordSaveTokenAsync(userName, password);

        return status;
    }

    private async Task PasswordSaveTokenAsync(string userName, string password)
    {
        var baseAddress = Config.WebApiAddress;

        var client = new HttpClient { BaseAddress = baseAddress };
        var response = await client.PostAsync("Token", new StringContent(String.Format("grant_type=password&username={0}&password={1}", userName, password), Encoding.UTF8));

        response.EnsureSuccessStatusCode();

        var tokenResponse = await response.Content.ReadAsStringAsync();
        var json = JObject.Parse(tokenResponse);

        var token = json["access_token"].ToString();
        var expires = DateTime.Parse(json[".expires"].ToString());

        HttpContext.Current.Response.Cookies.Add(new HttpCookie("AccessToken")
        {
            Value = token,
            HttpOnly = true,
            Expires = expires,
        });

        HttpContext.Current.Session["AccessToken"] = token;
    }
}

答案 1 :(得分:-1)

你也可以把它放在一个饼干里。

请务必将Cookie标记为仅限http