将JWT存储在cookie httpOnly true和第二cookie httpOnly false中以存储用户详细信息

时间:2019-09-09 02:00:59

标签: node.js angular cookies jwt

我在服务器端的NodeJS 12 Express 4和客户端的Angular 8 SPA中构建Web应用程序。

服务器端登录路由用于运行护照认证策略。用户通过身份验证后,将返回用户对象。将创建一个JWT并用用户对象签名。

jwt = jwtCtrl.generateJwt(user);

然后将JWT放置在cookie中,并将 httpOnly 标志设置为true。 Cookie存储在浏览器中,并将在所有HTTP请求中进行身份验证和授权,并发送回服务器。

res.cookie('jwt', jwt, options.jwtCookieOptions);

如果我的理解正确,则 httpOnly 标志必须为 true ,以防止XSS攻击。 httpOnly标志可防止任何客户端javascript访问cookie。 Cookie包含身份验证令牌,因此客户端不应访问它。

但是,Angular SPA确实需要访问某些用户属性,例如电子邮件地址和访问级别。

我创建了SECOND cookie来发送用户详细信息,而不是公开'jwt'cookie。 “用户” cookie的httpOnly设置为false,以便客户端可以访问。

通过这种方式,“ jwt” cookie被发送回服务器进行身份验证,并受到httpOnly的保护,而SPA仅将“用户” cookie用于显示目的,例如,如果用户具有管理员访问权限级别。所有身份验证和查询将仅基于'jwt'cookie。

问题:

以下示例中的代码可以正常工作,以便在快递服务器中创建两个cookie并重定向回有角度的spa客户端。这两个Cookie的maxAge值相同。我只是想知道以这种方式发送两个不同的cookie是否是#1良好做法#2建议#3可持续的。还是通过这种或更好的方法实现目标存在一些缺陷?请注意,由于服务器正在重定向回客户端,因此我故意不在标头Authorization Bearer中发送JWT。另外,httpOnly似乎是在客户端上存储JWT的更好方法。

// Set options
loginCtrl.setCookieOptions = () => {

  const COOKIE_MAX_AGE_MINS = Number(process.env.COOKIE_MAX_AGE_MINS) ? Number(process.env.COOKIE_MAX_AGE_MINS) : 480;

  /**
   * JWT cookie options
   * Cookie to store JWT authentication token
   * httpOnly set to true for web server access only
   *
   */
  const jwtCookieOptions = {
    maxAge: COOKIE_MAX_AGE_MINS * 1000 * 60,
    signed: true,
    secureCookie: true,
    sameSite: true,
    // Prevent client side javascript access, this cookie contains auth token
    httpOnly: true,
    // Attach cookie to all requests in this path
    path: '/api'
  }

  /**
   * User cookie options
   * Cookie to store user properties
   * httpOnly set to false to allow client access
   * The user cookie contains email address and access level only
   *
   */
  const userCookieOptions = {
    maxAge: COOKIE_MAX_AGE_MINS * 1000 * 60,
    signed: false,
    secureCookie: true,
    sameSite: true,
    // Allow client side javascript access, this cookie does not contain auth token
    httpOnly: false,
    // Attach cookie to all requests in this path
    path: '/'
  }

  return {
    jwtCookieOptions: jwtCookieOptions,
    userCookieOptions: userCookieOptions
  }

}

router.post('/login', (req, res, next) => {

  /* Authentication logic to set user... */
  passport.authenticate('local', function (err, user, info) {

    /* AUTHENTICATION SUCCESS */
    if (user) {
      // Generate JWT token
      let jwt;
      jwt = jwtCtrl.generateJwt(user);

      // Set cookie options
      const options = loginCtrl.setCookieOptions();

      // Store JWT in a cookie to be sent back to server for authentication in every request
      // Since it contains auth jwt token this cookie is accessible to server only
      res.cookie('jwt', jwt, options.jwtCookieOptions);
      // Store user properties in a cookie to be read by client side app
      res.cookie('user',
        JSON.stringify({ EmailAddress: user.EmailAddress, AccessLevel: user.AccessLevel }),
        options.userCookieOptions
      );

      // Redirect to the Angular SPA client
      return res.redirect(302, 'http://angular-spa-client.com/');
    }

  })(req, res);

});

0 个答案:

没有答案