如何解决NextAuth Hasura 刷新令牌
我正在尝试为 Hasura 身份验证和授权设置 NextAuth。由于 Hasura 需要自定义 jwt 声明,因此我无法使用 OAuth 提供程序提供的默认访问令牌。所以我在 [...nextauth].js 中使用 encode 块来编码自定义 jwt 令牌,一切正常。但我不知道如何为我的自定义令牌实现刷新令牌。下面是我的“pages/api/auth/[...nextauth].js”
import * as jwt from "jsonwebtoken";
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
export default NextAuth({
providers: [
Providers.Google({
clientId: process.env.GOOGLE_CLIENT_ID,clientSecret: process.env.GOOGLE_CLIENT_SECRET,authorizationUrl:
"https://accounts.google.com/o/oauth2/v2/auth?prompt=consent&access_type=offline&response_type=code",}),],secret: process.env.SECRET,session: {
jwt: true,},jwt: {
secret: process.env.SECRET,encode: async ({ secret,token,maxAge }) => {
const jwtClaims = {
sub: token.id,name: token.name,email: token.email,picture: token.picture,iat: Date.now() / 1000,exp: Math.floor(Date.now() / 1000) + 60,"https://hasura.io/jwt/claims": {
"x-hasura-allowed-roles": ["user"],"x-hasura-default-role": "user","x-hasura-role": "user","x-hasura-user-id": token.id,};
const encodedToken = jwt.sign(jwtClaims,secret,{ algorithm: "HS256" });
return encodedToken;
},decode: async ({ secret,maxAge }) => {
const decodedToken = jwt.verify(token,{ algorithms: ["HS256"] });
return decodedToken;
},pages: {
// signIn: '/auth/signin',// Displays signin buttons
// signOut: '/auth/signout',// Displays form with sign out button
// error: '/auth/error',// Error code passed in query string as ?error=
// verifyRequest: '/auth/verify-request',// Used for check email page
// newUser: null // If set,new users will be directed here on first sign in
},// Callbacks are asynchronous functions you can use to control what happens
// when an action is performed.
// https://next-auth.js.org/configuration/callbacks
callbacks: {
// async signIn(user,account,profile) { return true },// async redirect(url,baseUrl) { return baseUrl },async session(session,token) {
const encodedToken = jwt.sign(token,process.env.SECRET,{
algorithm: "HS256",});
session.token = encodedToken;
session.id = token.id;
return Promise.resolve(session);
},async jwt(token,user,profile,isNewUser) {
const isUserSignedIn = user ? true : false;
// make a http call to our graphql api
// store this in postgres
if (isUserSignedIn) {
token.id = profile.id.toString();
}
return Promise.resolve(token);
},// Events are useful for logging
// https://next-auth.js.org/configuration/events
events: {},// Enable debug messages in the console if you are having problems
debug: true,});
有人能告诉我在使用自定义 jwt 令牌时如何使用 next-auth 处理刷新令牌吗?
解决方法
我目前正在使用我在 next-auth
问题页面上的帖子 here 中找到的方法。
本质上,我们使用了 clientMaxAge
选项的组合,您可以传递给提供程序来重新获取会话,从而重新运行 jwt 回调。我不确定我是否正确使用了 keepAlive
属性,但目前看来轮询是正确的,尽管您可能需要对此进行试验。
在您的 JWT 回调中,您可以拥有将检查现有到期时间与另一个逻辑的逻辑,并从您的服务器获取新令牌以分配给会话。
//_app.tsx
const sessionOptions = {
clientMaxAge: 60 * 30,// Re-fetch session if cache is older than 30 minutes
keepAlive: 60 * 30,// Send keepAlive message every hour
};
<Provider options={sessionOptions} session={pageProps.session}>
..
</Provider>
// [...nextauth].ts
const callbacks: CallbacksOptions = {
async jwt(token: any,user: any) {
if (user) {
token.accessToken = user.token;
token.expires = Date.now() + user.config.USER_SESSION_LENGTH_IN_SECONDS * 1000;
}
// Don't access user as it's only available once,access token.accessToken instead
if (token?.accessToken) {
const tokenExpiry = token.expires;
const almostNow = Date.now() + 60 * 1000;
if (tokenExpiry !== undefined && tokenExpiry < almostNow) {
// Token almost expired,refresh
try {
const newToken = await api.renewToken(token.accessToken); // calling external endpoint to get a new token
// re-assign to the token obj that will be passed into the session callback
token.accessToken = newToken.token;
token.expires = Date.now() + user.config.USER_SESSION_LENGTH_IN_SECONDS * 1000;
} catch (error) {
console.error(error,'Error refreshing access token');
}
}
}
return token;
},async session(session: any,user: any) {
session.accessToken = user.accessToken;
session.expires = user.expires;
return session;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。