如何在NextAuth的IdentityServer4Provider中设置grant_type参数
问题背景
需要使用NextAuth与IdentityServer4实现身份认证,初始编写的Provider配置代码如下:
import NextAuth from "next-auth" import IdentityServer4Provider from "next-auth/providers/identity-server4"; export default NextAuth({ // Configure one or more authentication providers providers: [ IdentityServer4Provider({ id: "identity-server4", name: "IdentityServer4", issuer: process.env.NEXT_PUBLIC_IDENTITY_SERVER, clientId: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET }) ], callbacks: { }, secret: process.env.NEXTAUTH_SECRET, })
当前需求是为授权流程添加值为client_credentials的grant_type参数,但查看NextAuth内置IdentityServer4Provider的源码后发现,默认配置未提供grant_type相关配置项,其默认实现代码如下:
/** @type {import(".").OAuthProvider} */ export default function IdentityServer4(options) { return { id: "identity-server4", name: "IdentityServer4", type: "oauth", wellKnown: `${options.issuer}/.well-known/openid-configuration`, authorization: { params: { scope: "openid profile email" } }, checks: ["pkce", "state"], idToken: true, profile(profile) { return { id: profile.sub, name: profile.name, email: profile.email, image: null, } }, options, } }
手动构造携带对应grant_type的POST令牌请求可正常调用接口,请求示例如下图所示:
解决方案
不需要修改NextAuth源码,通过内置Provider的配置覆盖能力即可实现自定义grant_type,以下是可直接复用的配置方案:
最小改动配置
直接在现有IdentityServer4Provider初始化参数中补充token请求配置,同时调整校验规则适配client_credentials模式:
import NextAuth from "next-auth" import IdentityServer4Provider from "next-auth/providers/identity-server4"; export default NextAuth({ providers: [ IdentityServer4Provider({ id: "identity-server4", name: "IdentityServer4", issuer: process.env.NEXT_PUBLIC_IDENTITY_SERVER, clientId: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, // 覆盖token端点配置,指定自定义grant_type token: { url: `${process.env.NEXT_PUBLIC_IDENTITY_SERVER}/connect/token`, params: { grant_type: "client_credentials" } }, // client_credentials模式不涉及用户授权跳转,需要移除默认的PKCE校验 checks: ["state"] }) ], secret: process.env.NEXTAUTH_SECRET, // 调试阶段可开启debug模式,打印完整OAuth请求日志确认参数是否正确携带 debug: process.env.NODE_ENV === "development" })
高自定义度配置
如果后续需要调整更多OAuth流程逻辑,可以完全放弃内置的IdentityServer4Provider封装,直接传入完整的OAuth配置,灵活性更高:
import NextAuth from "next-auth" export default NextAuth({ providers: [ { id: "identity-server4", name: "IdentityServer4", type: "oauth", wellKnown: `${process.env.NEXT_PUBLIC_IDENTITY_SERVER}/.well-known/openid-configuration`, authorization: { params: { scope: "openid profile email" } }, token: { url: `${process.env.NEXT_PUBLIC_IDENTITY_SERVER}/connect/token`, params: { grant_type: "client_credentials" } }, checks: ["state"], clientId: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, idToken: true, profile(profile) { return { id: profile.sub, name: profile.name, email: profile.email, image: null, } }, } ], secret: process.env.NEXTAUTH_SECRET, })
注意事项
client_credentials属于服务端间认证的授权模式,没有用户参与的登录跳转流程,如果你的场景是普通用户登录认证,应该使用默认的authorization_code授权模式,不要随意替换grant_type。- 如果IdentityServer4端对client_credentials模式配置了单独的scope,需要同步在
token.params中添加对应scope参数,否则会报权限不足错误。
内容的提问来源于stack exchange,提问作者Falcon Stakepool
相关产品推荐
相关产品推荐

