首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NextAuth -句柄刷新令牌旋转(Reddit)与数据库

NextAuth -句柄刷新令牌旋转(Reddit)与数据库
EN

Stack Overflow用户
提问于 2022-08-26 22:53:13
回答 2查看 277关注 0票数 2

Reddit的访问令牌有效期为1小时,但我希望登录到我的应用程序的用户能够在Reddit上发表评论。这意味着我需要在他们的访问令牌过期后刷新它。由于我使用的是数据库(PlanetScale + Prisma),而不是JWT策略,所以这里找到的文档https://next-auth.js.org/tutorials/refresh-token-rotation对我没有用处(从未调用jwt回调)。

据我所理解,这意味着在不每次访问数据库的情况下检查session回调中的过期并刷新令牌是不可能的。

如果我想刷新数据库中的访问令牌,我可以做什么?我是否应该使用JWT策略,即使我使用的是数据库?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-08-27 12:14:03

要在使用数据库策略时执行刷新令牌旋转,可以执行以下操作:

代码语言:javascript
复制
async function refreshAccessToken(session: Session) {
  if (!session.user?.id) {
    return;
  }

  const {
    id,
    refresh_token: refreshToken,
    expires_at: expiresAt,
  } = (await prisma.account.findFirst({
    where: { userId: session.user.id, provider: "reddit" },
  })) ?? {};

  if (!id || !refreshToken) {
    return;
  }

  // If expired refresh it
  if (expiresAt && Date.now() / 1000 > expiresAt) {
    const authorizationString = Buffer.from(
      `${process.env?.["REDDIT_CLIENT_ID"]}:${process.env?.["REDDIT_CLIENT_SECRET"]}`,
    ).toString("base64");

    const headers = {
      Authorization: `Basic ${authorizationString}`,
      "Content-Type": "application/x-www-form-urlencoded",
    };

    const urlSearchParams = new URLSearchParams();
    urlSearchParams.append("grant_type", "refresh_token");
    urlSearchParams.append("refresh_token", refreshToken);
    urlSearchParams.append("redirect_uri", `${process.env?.["NEXTAUTH_URL"]}/api/auth/callback/reddit`);

    const { data } = await axios.post<RedditResponse>("https://www.reddit.com/api/v1/access_token", urlSearchParams, {
      headers,
    });

    await prisma.account.update({
      where: { id },
      data: {
        access_token: data.access_token,
        expires_at: Math.floor(Date.now() / 1000) + data.expires_in,
        refresh_token: data.refresh_token,
        token_type: data.token_type,
        scope: data.scope,
      },
    });
  }
}

我想你可以在任何地方用这个。我不知道在session回调中使用它是否有意义,因为它可能会影响性能,所以每次您确实需要访问令牌时就调用它吧?我不知道这方面的最佳做法是什么.

票数 2
EN

Stack Overflow用户

发布于 2022-08-27 09:45:31

经过几个小时的修补,我才发现如何将刷新令牌放到数据库中!

下一个令牌刷新教程的第一部分之后,将授权param添加到提供者选项中

代码语言:javascript
复制
const GOOGLE_AUTHORIZATION_URL =
  "https://accounts.google.com/o/oauth2/v2/auth?" +
  new URLSearchParams({
    prompt: "consent",
    access_type: "offline",
    response_type: "code",
  });

代码语言:javascript
复制
export default NextAuth({
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET,
      authorization: GOOGLE_AUTHORIZATION_URL,
    }),

这会让我很好的解决剩下的问题.希望它也适用于你!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73507135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档