【问题标题】:Cookies set by AngularJS are ignored after browser refreshAngularJS设置的cookies在浏览器刷新后被忽略
【发布时间】:2017-01-07 09:27:48
【问题描述】:

我正在使用 SQL、Angularjs、Node.js 和 Express 创建一个 Angularjs 单页应用程序,它使用护照和基本身份验证登录。当用户登录时,他们能够访问路径以编辑数据库中的项目。这一切都正常工作,问题是只要浏览器不刷新,cookie就会被发送。

如果浏览器刷新,令牌不再随请求一起发送,因此用户无法再访问路由,因为请求中没有令牌。但是,如果您在浏览器中查看 cookie,令牌仍然存在,只要服务器没有重新启动,令牌应该仍然有效。

还有其他由 Google Analytics 设置的 cookie,但它们每次都会随请求一起发送。如果我在app.run 中设置了一个cookie,它确实会持续存在并每次都随请求一起发送,只有在浏览器刷新后不会发送使用登录工厂创建的cookie。

我的登录工厂如下所示:

'use strict';

import * as customFunctions from '../../shared/methods/common-functions.js';

const userLoggingRESTResources = (app) => {

  app.factory('userLoggingRESTResources', ['$http', '$base64', '$cookies', '$window', ($http, $base64, $cookies, $window) => {
    return (user, callback) => {
      return {
        signIn: (user, callback) => {
          var encoded = $base64.encode(user.username + ':' + user.password);
          $http.get('/auth/login', {
              headers: {
                'Authorization': 'Basic ' + encoded
              }
            })
            .success((data) => {

              $cookies.put('token', data.token);
              $cookies.put('interopAdmin', data.admin);
              $window.sessionStorage.token = data.token;
              $http.defaults.headers.common.Authorization = data.token;
              callback(null);
            })
            .error((data) => {
              callback(data);
            })
        }

      };
    }


  }])
}

module.exports = userLoggingRESTResources;

我的登录路径如下所示:

  router.get('/login', passport.authenticate('basic', {
    session: false
  }), (req, res) => {
    let userJSON = {
      randomString: req.user.dataValues.randomString,
      id: req.user.dataValues.id
    };
    res.req.headers.authorization = 'hahaha';
    for (let key in res.req.rawHeaders) {
      if (res.req.rawHeaders[key].slice(0, 5) === 'Basic') {
        res.req.rawHeaders[key] = 'Basic xxxx';
      }

    }
    req.user.$modelOptions.instanceMethods.generateToken(userJSON, process.env.SECRET_KEY, (err, token) => {
      if (err) {
        console.log(err);
        return res.status(500).json({
          msg: 'error generating token'
        });
      }

      res.status('200').header('token', token).json({
        token: token,
        'admin': req.user.dataValues.isAdmin
      });
    });
  });

我正在使用来自 npm 的 eat 模块来处理令牌的解码:

'use strict';

const eat = require('eat');
const models = require('../models');
const User = models.User;
const clc = require('cli-color');

module.exports = (secret) => {
  return (req, res, next) => {
    let token = req.cookies.token || req.headers.token || req.body.token || req.headers.authorization;
    if (!token) {
      console.log(clc.white.bgRed('no token in request'));
      return res.status(401).json({
        msg: 'not authorized'
      });
    }
    eat.decode(token, secret, (err, decoded) => {
      if (err) {
        console.log(clc.white.bgRed('Error, login failed:   '), err);
        return res.status(401).json({
          msg: 'not authorized'
        });
      }

      User.findOne({
          where: {
            id: decoded.id
          }
        })
        .then((user) => {
          if (!user) {
            console.log(clc.white.bgRed('user not found'));
            return res.status(401).json({
              msg: 'not authorized'
            });
          }

          req.user = user;
          next();
        })
        .error((error) => {
          console.log(clc.white.bgRed('Error:  '), err);
          return res.status(401).json({
            msg: 'not authorized'
          });
        });
    });
  };
};

如果您想查看代码的另一部分,请告诉我。感谢您提前提供的所有帮助!

【问题讨论】:

  • 为你的令牌使用 angular-storage github.com/auth0/angular-storage
  • 只是为了清楚。您在控制台中收到“请求中没有令牌”错误是吗?
  • @Yashua 是的,你是对的,我收到“请求中没有令牌”。
  • 您确认您的某些服务器令牌是从req.cookies 读取的吗?您的身份验证方式可能来自很多地方,我想知道它是否每次都在读取 req.header,这可能表明整个 cookie 读取问题。
  • @Yashua 是的,它们是从req.cookies 中读取的,最初我只使用$cookie 来存储令牌,但是当它无法刷新时,我尝试将其存储在更多/不同的地方,看看我是否可以在刷新后发送其中的任何一个

标签: javascript angularjs node.js express cookies


【解决方案1】:

你说 cookie 没有发送,然后你说 cookie 在浏览器中。这两种说法相互矛盾。如果它们在浏览器中,也许您的 Angular 应用程序只需要读取它们?如果它们没有被发送,也许您需要在服务器上使用某种会话来存储令牌/任何东西,以便您可以将其作为 cookie 发送回来。

【讨论】:

  • cookies 由 Angular 从登录路由的数据响应中设置,然后它们存在于浏览器中,然后 cookie 从浏览器发送到我的节点路由的后续 $http get 请求。如果页面没有刷新,cookie 会随着每个后续请求不断发送,并且一切正常。但是如果浏览器刷新,cookies 仍然在浏览器上,但由于某种原因,它们不再随请求一起发送。对不起,如果我没有很好地表达它。
【解决方案2】:

所以我想通了。我将/admin/login 用于我的登录路由,将/admin/whatever 用于需要身份验证的其他路由,因此cookie 设置为路径:/admin/login,因为我只在第一次登录时使用该路由,这就是cookie 的原因第一次发送,但在随后的请求中没有发送。

为了解决这个问题,我在设置 cookie 时将路径设置为根目录:

$cookies.put('token', data.token, {'expires': expireDate, 'path': '/'});

现在 cookie 随所有请求一起发送!感谢所有提示和帮助:-)

【讨论】:

    猜你喜欢
    • 2016-04-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 2015-04-03
    相关资源
    最近更新 更多