我正在尝试在我的 NextJS 项目中设置身份验证,并且我正在使用 Next-Auth。我目前正在尝试设置一个简单的
GET /me
路由,该路由将使用成功的 Auth0 会话登录检索到的 access_token 通过 React 查询进行命中。
但是:从 Next-Auth w/Auth0 useSession() 收到的 access_token 格式错误
编辑:我认为问题在于 next-auth / auth0 将令牌存储为加密的 JWE。我需要弄清楚如何解密并将其传递给我的 api
在我的
pages > api > auth > [...nextauth].js
我有以下配置
const authOptions = {
providers: [
Auth0Provider({
clientId: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
issuer: process.env.AUTH0_ISSUER,
idToken: true,
}),
],
// Configure callbacks 👉 https://next-auth.js.org/configuration/callbacks
callbacks: {
// The JWT callback is called any time a token is written to
jwt: ({ token, user, account, profile, isNewUser }) => {
if (account) {
token.access_token = account.access_token;
token.id_token = account.id_token;
token.auth0_id = token.sub;
token.type = account.token_type;
}
delete token.name;
delete token.picture;
delete token.sub;
return token;
},
// The session callback is called before a session object is returned to the client
session: ({ session, user, token }) => {
const newSession = {
user: {
auth0_id: token.auth0_id,
email: token.email,
},
token: {
access_token: token.access_token,
id_token: token.id_token,
token_type: token.type,
},
};
return newSession;
},
},
secret: process.env.NEXTAUTH_SECRET,
};
export default NextAuth(authOptions);
在 Auth0 仪表板中:
Auth0 > Applications > Applications > <PROJECT_NAME> > AdvancedSettings > OAuth
signature algorithm
是 RS256
这里我使用
const { data: session, status } = useSession();
来提取当前会话的值(它与 session callback
的 pages > api > auth > [...nextauth].js
中创建的形状相匹配——并且具有 access_token
)
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
return (
<SessionProvider session={session}>
<QueryClientProvider client={queryClient}>
<Component {...pageProps} />
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
</SessionProvider>
);
}
对于向服务器发送的每个 API 请求,我都会设置标头
if (token) headers["authorization"] = `Bearer ${token}`;
headers["Content-Type"] = "application/json";
我创建了一个
auth
中间件函数,有两个用途。
下面是
auth
中间件
// Auth0
import { isPublicRoute } from "../services/auth0/index.js";
import { expressjwt } from "express-jwt";
import jwks from "jwks-rsa";
// 👀 I have copied this directly from the Auth0 Dashboard: Applications > APIs > QuickStart
// 🚨 the express-jwt library is failing - error below
const validator = expressjwt({
secret: jwks.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: "https://dev-ikfyop4g.us.auth0.com/.well-known/jwks.json",
}),
audience: "thunderbolt",
issuer: "https://dev-ikfyop4g.us.auth0.com/",
algorithms: ["RS256"],
});
// NOTE: 👀 we are not actually getting to this function
// This function will retrieve the user and feed it into the request
// into a populated user model, if the id is not in the database it
// will create a new user and pull the base data from auth0
const userInjector = async (req, res, next) => {
if (isPublicRoute(req)) return next();
if (!req.auth0?.sub) throw badImplementation("JWT missing in userInjector");
req.user = await userFromReq(req);
console.log("THE USER INJECTOR RESULT :: req.user", req.user);
next();
};
const auth = () => {
return [validator, userInjector];
};
export default auth;
在我的服务器内部,我导入这个
auth
中间件函数并像这样使用
server.use(auth());
express-jwt
错误UnauthorizedError: jwt malformed
at new UnauthorizedError (/Users/mrt/Documents/MrT/code/M/bolt/node_modules/express-jwt/dist/errors/UnauthorizedError.js:22:28)
at /Users/mrt/Documents/MrT/code/M/bolt/node_modules/express-jwt/dist/index.js:133:35
at step (/Users/mrt/Documents/MrT/code/M/bolt/node_modules/express-jwt/dist/index.js:33:23)
at Object.next (/Users/mrt/Documents/MrT/code/M/bolt/node_modules/express-jwt/dist/index.js:14:53)
at fulfilled (/Users/mrt/Documents/MrT/code/M/bolt/node_modules/express-jwt/dist/index.js:5:58)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
我从 Auth0 收到的 access_token 格式错误。经过进一步调查,我同意。我收到的 AccessToken(作为 JWT)有 5 个部分(各部分是用句点分隔的字符串.
。
Access Token From Auth0 Session
eyJhbGc<REMOVED_CHUNK>uYXV0aDAuY29tLyJ9.. // 2 period w/ nothing inbetween??
zOKQ2<REMOVED_CHUNK>rSm6.
9qbS5yndGKkrZ9Tc_dL8ZOuHtp_-e58uGqvGHgcpcFS8-s6SEHJYZ0_g7Ii7aYQe4AdbeK9ekW-704X_6C1r5JH3-9yBz<REMOVED_CHUNK>6Rn3Q8U0YC_x8Vp9pF_EA4GHjevXrh3HFBzCY4AEAx-Rmnzk4tZDgk3oU2rsY1NleMTwpIj0h29KIsukg113uMt5KCWKVnosSI-psaBu<REMOVED_CHUNK>lf0R_y5ClcXF6XY0ezIvuwoSQOmhulMlPsTxzBVGeoIhsooNntgAc4s.
ojmkoO_CO<REMOVED_CHUNK>URg
如果一切都配置为 RS256,为什么 Next-Auth w/Auth0 会向我发送格式错误的 JWT。编辑:由 5 部分组成的 JWT 是 JSON Web 加密 (JWE) 令牌...?