在哪里存储访问和刷新令牌

Where to store Access and Refresh tokens

我正在通过 JavaScript 从我的 ASP.NET MVC 网络应用程序向我的网络 API 发出 OAuth2 调用以验证我的用户并获取令牌。 Web API 访问 SQL 服务器数据库,其中使用 Identity 和典型的 AspNetUsers 表存储用户登录信息。我的 API 调用 returns 一个 20 分钟的访问令牌和一个 2 周的刷新令牌。 API 和消费应用程序是我们正在开发的产品,我们的客户将注册这些产品。也就是说,所有的代码都在我们这边。

我知道我必须通过传递 API 刷新令牌在访问令牌过期之前刷新它。我的问题是...我应该将访问和刷新令牌存储在客户端的什么位置,以便在我的 JavaScript 中进行后续 API 调用或刷新令牌?网上的人说在客户端存储任何东西都是不好的,cookie 是不安全的,等等,但没有提供任何解决方案。本地存储?但当然这些是 JavaScript 中的 Ajax 调用,我们正在对 API 进行调用,因此令牌需要存在于客户端的某个地方!试图弄清楚这一点让我发疯。我知道我至少需要使用 HTTPS。

授权令牌是您始终可以使用刷新令牌获得的东西。因此,有一个拦截器来验证传入和传出请求并将身份验证令牌存储在那里。来到刷新令牌,在我们的应用程序中,我们最初存储在 cookie 中,后来移动到本地存储。

我建议您在数据库中创建一个 table 来存储刷新令牌和访问令牌。 Table 结构如下所示

ID,Access_Token,Refresh_Token,LastUpdated_Time

每当您使用访问令牌调用 API 时,请检查 当前时间 LastUpdated_Time 的 token ,如果超过一个小时,您的 token 将失效,因此您需要使用刷新 token 获取另一个有效的 token 。 在我的应用程序中,我有 55 分钟的令牌寿命,之后令牌失效。

代码

if (dateTimeDiff > 55) {
    var request = (HttpWebRequest) WebRequest.Create("https://www.googleapis.com/oauth2/v3/token");
    var postData = "refresh_token=your refresh token";
    postData += "&client_id=your client id";
    postData += "&client_secret=your client secret";
    postData += "&grant_type=refresh_token";

    var data = Encoding.ASCII.GetBytes(postData);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.ContentLength = data.Length;
    request.UseDefaultCredentials = true;

    using(var stream = request.GetRequestStream()) {
        stream.Write(data, 0, data.Length);
    }
    var response = (HttpWebResponse) request.GetResponse();
    string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();

}

响应将包含新的访问令牌,不要忘记用 LastUpdated_Time 和新令牌更新您的 table。

您可以尝试将令牌存储在 localStorage 上,我现在正在做的是(我正在使用 typescript 和 react,但我认为它会为您的网络应用程序提供线索):

const msg = await login({ ...values, type });
let accessToken = msg.accessToken;
window.localStorage.setItem("x-access-token", accessToken);