【问题标题】:CORS error when trying to redirect from http://localhost:3000 to https://api.twitter.com in Next.js using next-connect?尝试使用 next-connect 在 Next.js 中从 http://localhost:3000 重定向到 https://api.twitter.com 时出现 CORS 错误?
【发布时间】:2022-01-03 10:33:43
【问题描述】:

我试图让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 个月前问过the same question,但是这个问题适用于打开一个弹出窗口并在那里进行重定向,这个人想要一个重定向在同一页面本身。

我也尝试了相同的答案,但它不起作用并且它仍然给我这个代码的 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

【问题讨论】:

    标签: node.js express next.js cors next-connect


    【解决方案1】:

    As mentioned here,Twitter API 不支持 CORS。

    所以我不能只在api/auth/twitter/generate-auth-link.ts 中执行res.redirect(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
    

    它成功了!

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 1970-01-01
      • 2019-07-21
      • 2015-04-10
      • 2017-09-02
      • 2021-08-31
      • 1970-01-01
      • 2021-11-18
      • 2017-04-29
      相关资源
      最近更新 更多