首页 文章

Koa ctx.session在重定向后丢失了

提问于
浏览
0

我有两个Node.js服务器应用程序 . 第一个在localhost:8081上运行Koa.JS,而第二个在localhost:8080上运行Vue.JS . 在两个服务器中,我使用HTTP而不是HTTPS .

Koa.JS服务器使用Passport.JS执行oAuth2登录流程,并提供 endpoints 以从API获取数据并将承载令牌传递给Authorization标头 .

Vue.js服务器负责客户端代码 . 它使用axios库调用Koa endpoints .

如果我打开浏览器,并针对Koa服务器测试登录流程,那么一切正常并正常工作 . 以下是步骤:

  • localhost:8081 / api / oauth / authenticate
router.get(
  '/authenticate',
  passport.authenticate(
    'oauth2',
    { scope: config.scope }
  ))
  • 用户登录并授予访问权限

  • 完成后,回调称为localhost:8081 / api / oauth / callback

router.get(
  '/callback',
  ctx => {
    return passport.authenticate(
      'oauth2',
      async (err, user) => {
        if (err) ctx.throw(err)
        const tokenSession = new token(ctx.session)
        await ctx.login(user)
        tokenSession.setPublicCredentials(user)
        ctx.redirect(`${config.vuehost}/auth?isUserLoggedIn=true`)
      })(ctx)
  })
  • 会话与用户信息一起保存

  • 用户打开新选项卡转到localhost:8081 / api / user / profile

router.get(
  '/user/profile',
  async (ctx) => {
    if (ctx.isAuthenticated) {
      const options = {
        headers: { Authorization: `Bearer ${ctx.session.passport.user.access_token}` },
        json: true,
        method: 'GET',
        uri: 'https://developer.mycoolapi.com/userprofile/v1/users/@me'
      }
      const response = await rp(options)
      ctx.body = JSON.stringify(response)
    } else {
      ctx.throw(401)
    }
  }
)
  • Koa服务器调用其他API来检索用户配置文件数据,Vue.js应用程序获取正确的JSON响应

但是,如果我执行以下操作,ctx.session会丢失:

  • 导航到localhost:8080(Vue.js服务器)

  • 通过重定向到Koa endpoints localhost:8081 / api / oauth / authenticate来执行登录

  • 登录并授予访问权限

  • On Koa / callback重定向回localhost:8080 / auth?isUserLoggedIn = true

  • 在Vue应用程序中,使用此命令检索查询参数 . $ route.query.isUserLoggedIn,如果为true,则调用Koa endpoints 以获取用户配置文件数据localhost:8081 / api / user / profile

axios.get('http://localhost:8081/api/user/profile')
    .then (response => {
      console.info(`\nsetUserData response: ${JSON.stringify(response)}\n`)
    })
    .catch (err => {
      console.info(`\nsetUserData error: ${JSON.stringify(err)}\n`)
    })

最后一步返回401 Unauthorized .

经过进一步调查,具有配置文件 endpoints 的Koa路由位于appRoutes中间件中 . 这个中间件就在app.use(requireLogin)中间件之后,它检查会话是否经过身份验证(ctx.isAuthenticated()) .

'use strict'

const requireLogin = async (ctx, next) => {
  if (ctx.isAuthenticated()) {
    await next()
  } else {
    ctx.status = 401
    ctx.body = {
      errors: [{ title: 'Login required', status: 401 }]
    }
  }
}
module.exports = requireLogin

这是发生401错误的地方,因为此时ctx会话为空 .

// Add routing
app.use(authRoutes.routes())
app.use(authRoutes.allowedMethods())
app.use(requireLogin)
app.use(appRoutes.routes())
app.use(appRoutes.allowedMethods())

我是否正在处理某种时间问题?我尝试在我的Koa server.js文件中评论头盔中间件,但这没有帮助 .

请注意,如果我在同一个浏览器会话中打开一个新选项卡并转到localhost:8081 / api / user / profile,它可以正常工作 . 只有当从Vue.js调用此 endpoints 时才会因ctx.sesssion为空而失败 .

有什么想法将ctx.session重置为null?

1 回答

  • 1

    仔细阅读本文后:https://medium.com/@xgwang/a-practical-guide-to-cors-51e8fd329a1f,我终于能够解决问题了 .

    在server.js中,将{credentials:true}传递给cors选项 .

    app.use(cors({credentials:true}))
    

    在Vue.js中,将axios默认设置为:

    axios.defaults.baseURL = 'http://localhost:8081'
    axios.defaults.withCredentials = true
    axios.defaults.crossDomain = true
    

    最后,当使用axios从Vue.js调用Koa endpoints 时,传递给头文件{'Access-Control-Allow-Credentials':true}

    this.$axios({
            headers: { 'Access-Control-Allow-Credentials': true },
            method: 'GET',
            url: `${config.koahost}/api/user/profile`
          })
    

相关问题