6

認証を処理するために next-auth を使用して、次の js アプリケーションを作成しています。

外部バックエンド API があるため、資格情報プロバイダーを使用しています。

問題は、バックエンドが httponly Cookie を送信することですが、クライアント側でリクエストを行ったときにそれらがブラウザーに添付されていないことです。

/pages/api/[...auth].js 内

import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';
import clientAxios from '../../../config/configAxios'

export default NextAuth({
    providers: [
        Providers.Credentials({
            async authorize(credentials) {
                try {
                    const login = await clientAxios.post('/api/login', {
                        username: credentials.username,
                        password: credentials.password,
                        is_master: credentials.is_master
                    })


                    const info = login.data.data.user
                    const token = {
                        accessToken: login.data.data.access_token,
                        expiresIn: login.data.data.expires_in,
                        refreshToken: login.data.data.refresh_token
                    }
                    // I can see cookies here
                    const cookies = login.headers['set-cookie']

                    return { info, token, cookies }
                } catch (error) {
                    console.log(error)
                    throw (Error(error.response.data.M))
                }
            }
        })
    ],
    callbacks: {
        async jwt(token, user, account, profile, isNewUser) {
            if (token) {
               // Here cookies are set but only in server side
               clientAxios.defaults.headers.common['Cookie'] = token.cookies
            }
            if (user) {
                token = {
                    user: user.info,
                    ...user.token,
                }
            }

            return token
        },
        async session(session, token) {
            // Add property to session, like an access_token from a provider.
            session.user = token.user
            session.accessToken = token.accessToken
            session.refreshToken = token.refreshToken

            return session
        }
    },
    session: {
        jwt: true
    }
})

私のaxios設定ファイル

import axios from 'axios';

const clientAxios = axios.create({

    baseURL: process.env.backendURL,
    withCredentials: true,
    headers:{
        'Accept' : 'application/json',
        'Content-Type' : 'application/json'
    }

});

export default clientAxios;

ページ コンポーネント

import { getSession } from "next-auth/client";
import clientAxios from "../../../config/configAxios";
import { useEffect } from "react"

export default function PageOne (props) {
    useEffect(async () => {
      // This request fails, cookies are not sent
      const response = await clientAxios.get('/api/info');
    }, [])

    return (
        <div>
           <h1>Hello World!</h1>
        </div>
    )
}

export async function getServerSideProps (context) {
    const session = await getSession(context)

    if (!session) {
        return {
            redirect: {
                destination: '/login',
                permanent: false
            }
        }
    }

    // This request works
    const response = await clientAxios.get('/api/info');
    
    return {
        props: {
            session,
            info: response.data
        }
    }
}

4

2 に答える 2

0

clientAxiosサーバーに返されるすべてのリクエストのレスポンスの一部としてサーバーが送信する Cookie を含めるように構成する必要があります。設定により api.defaults.withCredentials = true;、必要なものが得られるはずです。以下の vue アプリケーションの axios 構成を参照してください。

import axios from "axios";

export default ({ Vue, store, router }) => {
  const api = axios.create({
    baseURL: process.env.VUE_APP_API_URL
  });
  api.defaults.withCredentials = true; ------> this line includes the cookies
  Vue.prototype.$axios = api;
  store.$axios = api;
};

于 2021-05-18T23:37:52.293 に答える