結論
httpOptionsを使え
NextAuthでもNuxtAuthでも使える
secret: process.env.NUXTAUTH_SECRET,
providers: [
{
...
httpOptions: {
headers: {
'X-Api-Version': 11,
},
},
}
]
})
きっかけ
VroidHubApiをNuxt3で使いたかった
でもリファレンスはNext製..
Nuxt3でNextAuth v4を使いたい
普通に使う分には以下のライブラリを使えばOK
https://sidebase.io/nuxt-auth/getting-started
リファレンスを元に移植
https://github.com/pixiv/VRoidHub-API-Example/
上記のコードを元にNuxtAuthを使ってNuxt3に移植しようと試みる
ただ、Next製でかつNextAuthのv3だった
まずはNextAuthのバージョンをv3 -> v4へ書き直す
以下一部抜粋
params: { grant_type: 'authorization_code' },
accessTokenUrl: 'https://hub.vroid.com/oauth/token',
requestTokenUrl: 'https://hub.vroid.com/oauth/token',
authorizationUrl: 'https://hub.vroid.com/oauth/authorize?response_type=code',
profileUrl: 'https://hub.vroid.com/api/account',
これをこう
token: 'https://hub.vroid.com/oauth/token',
userinfo: 'https://hub.vroid.com/api/account',
authorization: {
url: 'https://hub.vroid.com/oauth/authorize',
params: { scope: 'default', response_type: 'code', grant_type: 'authorization_code' },
},
Headersをどこに..?
NextAuthのv3にはheadersの項目が存在しているがv4にはない
調べてもカスタムのプロバイダーを使ってる記事がほぼない
コードから探すことにした
隠されたパラメータ
NextAuth v4のリファレンスにはなかったhttpOptions
を見つけた
使えるものは以下
export type HttpOptions = Partial<
Pick<
https.RequestOptions,
| 'agent'
| 'ca'
| 'cert'
| 'crl'
| 'headers'
| 'key'
| 'lookup'
| 'passphrase'
| 'pfx'
| 'timeout'
>
>;
これでNuxt3でVroidHubApiを叩くことができた
Sample
/server/api/auth/[...].ts
import { NuxtAuthHandler } from '#auth';
export default NuxtAuthHandler({
secret: process.env.NUXTAUTH_SECRET,
providers: [
{
id: 'vroid',
name: 'VRoidHub',
type: 'oauth',
version: '2.0',
token: 'https://hub.vroid.com/oauth/token',
userinfo: 'https://hub.vroid.com/api/account',
authorization: {
url: 'https://hub.vroid.com/oauth/authorize',
params: { scope: 'default', response_type: 'code', grant_type: 'authorization_code' },
},
httpOptions: {
headers: {
'X-Api-Version': 11,
},
},
profile(profile) {
return {
id: profile.data.user_detail.user.id,
name: profile.data.user_detail.user.name,
image: profile.data.user_detail.user.icon.sq170.url,
};
},
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
},
],
callbacks: {
async jwt({ token, user, account, profile }) {
if (account?.accessToken) {
token.accessToken = account.access_token;
}
if (profile) {
token.id = profile.id;
}
return token;
},
async session({ session, token, user }) {
session.accessToken = token.accessToken;
return session;
},
async signIn({ user, account, profile }) {
console.log('signIn', user, account, profile);
return true;
},
},
});