Ошибка CORS при попытке перенаправить с http://localhost:3000 на https://api.twitter.com в Next.js с помощью следующего подключения?

Я пытаюсь получить redirect работать, но всегда получать сообщение об ошибке в консоли:

Доступ к выборке на https://api.twitter.com/oauth/authenticate?oauth_token='(перенаправлен с http: // localhost:3000 / api / auth / twitter / generate-auth-link) из источника » http: // localhost:3000 'заблокирован политикой CORS: на запрошенном ресурсе отсутствует заголовок'Access-Control-Allow-Origin'. Если непрозрачный ответ соответствует вашим потребностям, установите для режима запроса значение «no-cors», чтобы получить ресурс с отключенным CORS.

Я видел другие ответы на тот же вопрос, и на самом деле я обнаружил, что задал тот же вопрос ровно 2 месяца назад, но этот вопрос работает для открытия всплывающего окна и выполняет перенаправление там, и этот хочет перенаправления на та же самая страница.

Я также попробовал тот же ответ, но он не работает, и он все еще дает мне ошибку cors с этим кодом:

      .use((req, res, next) => {
    console.log('cors')
    res.setHeader('Access-Control-Allow-Origin', '*')
    res.setHeader(
        'Access-Control-Allow-Headers',
        'Origin, X-Requested-With, Content-Type, Accept, Authorization'
    )
    if (req.method == 'OPTIONS') {
        res.setHeader('Access-Control-Allow-Methods', 'PUT, POST, PATCH, DELETE, GET')
        return res.status(200).json({})
    }
    next()
})

Я также пробовал использовать этот код:

      const allowedOrigins = ['http://localhost:3000']

const options: cors.CorsOptions = {
    allowedHeaders: [],
    origin: allowedOrigins,
}

.use(cors(options))

но это тоже не работает.

Мой поток oauth выглядит так:

Нажмите "Войти" на http: // localhost:3000 → Перейдите на https://api.twitter.com/oauth/authenticate?oauth_token=xxxx → Перенаправьте обратно на http: // localhost:3000

Код для того же потока oauth выглядит так:

api / auth / twitter / generate-auth-link.ts

      import { NextApiResponse } from 'next'
import TwitterApi from 'twitter-api-v2'

import handler from '@/server/api-route'
import { SERVER_URL, TWITTER_CONFIG } from '@/utils/index'
import { NextIronRequest } from '@/types/index'

const generateAuthLink = async (req: NextIronRequest, res: NextApiResponse) => {
    // Generate an authentication URL
    const { url, oauth_token, oauth_token_secret } = await new TwitterApi({
        appKey: TWITTER_CONFIG.consumerKey,
        appSecret: TWITTER_CONFIG.consumerSecret,
    }).generateAuthLink(`${SERVER_URL}/api/auth/twitter/get-verifier-token`)

    req.session.twitter = {
        oauth_token,
        oauth_token_secret,
    }

    await req.session.save()

    // redirect to the authentication URL
    res.redirect(url)
}

export default handler().get(generateAuthLink)

api / auth / twitter / get-verifier-token.ts

      import { NextApiResponse } from 'next'
import TwitterApi from 'twitter-api-v2'

import handler from '@/server/api-route'
import { SERVER_URL, TWITTER_CONFIG } from '@/utils/index'
import { NextIronRequest } from '@/types/index'

const getVerifierToken = async (req: NextIronRequest, res: NextApiResponse) => {
    // check query params and session data
    const { oauth_token, oauth_verifier } = req.query

    if (typeof oauth_token !== 'string' || typeof oauth_verifier !== 'string') {
        res.status(401).send('Oops, it looks like you refused to log in..')
        return
    }

    if (!req.session.twitter)
        throw new Error("Can't find `oauth_token` & `oauth_token_secret` in `req.session.twitter`")

    const oauth_token_secret = req.session.twitter.oauth_token_secret

    if (typeof oauth_token_secret !== 'string') {
        res.status(401).send('Oops, it looks like your session has expired.. Try again!')
        return
    }

    // fetch the token / secret / account infos (from the temporary one)
    const { client, accessToken, accessSecret } = await new TwitterApi({
        appKey: TWITTER_CONFIG.consumerKey,
        appSecret: TWITTER_CONFIG.consumerSecret,
        accessToken: oauth_token,
        accessSecret: oauth_token_secret,
    }).login(oauth_verifier)

    const { name, screen_name, email } = await client.currentUser()

    req.session.twitter = { oauth_token: accessToken, oauth_token_secret: accessSecret }
    req.session.user = { name, screen_name, email }
    await req.session.save()

    res.redirect('/app')
}

export default handler().get(getVerifierToken)

Как решить проблему cors, чтобы перенаправления работали правильно?

Когда я использовал next-auth, это сработало, но не могу понять из кода, где это происходит. Но я хочу точно такой же поток. Нажмите на Login и он перенаправляется на Twitter API, и когда он аутентифицируется, перенаправляется обратно на localhost.

1 ответ

Как упоминалось здесь, Twitter API не поддерживает CORS.

Так что я не мог просто сделать res.redirect(url)в api/auth/twitter/generate-auth-link.tsпоэтому вместо этого я отправил URL-адрес обратно, используя res.send({ url })& в интерфейсе я сделал следующее:

      import ky from 'ky'

const res: { url: string } = await ky.get('/api/auth/twitter/generate-auth-link').json()
window.location.href = res.url

И это сработало!

Другие вопросы по тегам