我使用 nuxt 3 和 @sidebase/nuxt-auth 进行 PKCE OAUTH2 身份验证流程以及使用 Laravel 护照的 Laravel API。我完成了 Laravel 端的身份验证流程的实现,并完成了 nuxt 端,获取令牌并保存它。
然后我使用 ofetch 创建了一个自定义拦截器,以便发送我在每次请求时从会话中获取的 access_token。
但是当访问令牌过期时,它不会自动刷新。
我缺少一些配置吗?或者刷新令牌是我必须编写的自定义逻辑?
我已经在 @sidebase/nuxt-auth 中尝试了 JWT 回调,但没有成功。
这是我当前的身份验证配置:
import {NuxtAuthHandler} from '#auth'
import useCustomFetch from "~/composables/useCustomFetch";
export default NuxtAuthHandler({
providers: [
{
id: 'passport',
name: 'Passport',
type: 'oauth',
version: '2.0',
authorization: {
url: "https://example.com/oauth/authorize",
params: {
scope: '',
prompt: 'front',
},
},
clientSecret: 'awd',
clientId: "96695f40-1578-4b7c-974b-181e0344dcac",
token: 'https://example.com/api/v1/oauth/token',
userinfo: 'https://example.com/api/v1/user',
checks: ['pkce'],
profile(profile: { success: { user: any } }) {
const data = profile.success.user
return {
id: data.id,
name: data.first_name + " " + data.last_name,
email: data.email,
};
},
}
],
cookies: {
},
callbacks: {
async jwt({token, account, user}) {
if (account && user) {
return {
access_token: account.access_token,
refresh_token: account.refresh_token,
accessTokenExpires: account.expires_at,
user
}
}
// @ts-ignore
if (Date.now() < token.accessTokenExpires * 1000) {
return token
}
return await refreshAccessToken(token);
},
async session({session, token}) {
// @ts-ignore
session.user = token.user
// @ts-ignore
session.access_token = token.access_token
// @ts-ignore
session.error = token.error
return session
},
},
events: {
async signOut() {
try {
await useCustomFetch('/oauth/tokens/revoke', {
method: 'POST'
})
} catch (e) {
console.log(e);
}
},
}
})
async function refreshAccessToken(token: any) {
try {
const url = "https://example.com/api/v1/oauth/token";
// @ts-ignore
const refreshedToken: AuthResponse = await $fetch(url, {
headers: {
"Content-Type": "application/json",
},
method: "POST",
body: {
grant_type: 'refresh_token',
refresh_token: token.refresh_token,
client_id: "96695f40-1578-4b7c-974b-181e0344dcac"
}
});
token.access_token = refreshedToken.access_token;
token.accessTokenExpires = Date.now() + refreshedToken.expires_at * 1000;
token.refresh_token = refreshedToken.refresh_token;
return {
...token
}
} catch (error) {
console.log(error)
return {
...token,
error: "RefreshAccessTokenError",
}
}
}
interface AuthResponse {
access_token: string,
refresh_token: string,
token_type: string,
expires_at: number,
}
您能展示如何获取和设置标头授权令牌吗?