安全地使用Json Web Tokens

时间:2016-02-26 15:20:55

标签: angularjs cookies sails.js passport.js jwt

我们最近一直在搜索如何使用 JWT 进行身份验证并重构我的应用程序以使用它们而不是会话,当我们将服务器端sails api与移动应用程序。

在构建金融科技产品时,安全性非常重要。

我正在使用 sails js 以及 passport-jwt 。我使用 AngularJS $ cookies.put 函数将令牌存储在浏览器cookie中。我的目标是尽可能确保此令牌不会被浏览器中的任何第三方劫持或使用,以便向授权用户发送服务器。

为了保护这个令牌,我了解到我应该用 HttpOnly标志存储这个cookie,以使其无法通过javascript访问,这意味着我将无法在客户端访问此令牌当执行ajax请求时,我需要在passport-jwt的请求头中连接令牌,以便能够使用服务器端的 fromAuthHeader()函数来提取它。

要做的另一件事是将Cookie的安全标志设置为true,以强制它仅通过SSL传输。

我的问题是:

  1. 我是否正确使用JWT确保最大安全性?
  2. 如果是,如何在angular $ cookies.put方法中设置cookie标志?。
  3. 如果我无法从客户端访问cookie,怎么办? 我让passport-jwt从服务器端访问它以进行身份​​验证吗?。
  4. 如果我将令牌放在标题中,我可以使用 angular $ http拦截器在ajax请求中执行此操作,我该怎么办 这对于需要身份验证的普通浏览器查看请求?。
  5. 使用sails CSRF保护,它会解决我的问题吗?。
  6. 感谢。

    我在研究中使用的链接: https://stormpath.com/blog/the-ultimate-guide-to-mobile-api-security/ https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage/

1 个答案:

答案 0 :(得分:0)

嗯,经过更多的研究,这是我提出的最安全认证的解决方案:

首先,您必须仅在服务器端设置和获取cookie(在本例中为sailsJS),这就是我们将httpOnly标志设置为true的原因:

res.cookie('cookieName', jwt, {
  secure: req.connection.encrypted ? true : false,
  httpOnly: true
});

请注意,我正在检查当前连接是否受到设置安全标志的保护,以便能够在localhost上以开发模式进行测试。

其次,为了使passport-jwt能够从cookie访问令牌以进行验证,您必须实现其存储库中提到的自定义提取器:

  

如果提供的提取器不能满足您的需求,您可以轻松完成   提供你自己的回调。例如,如果您正在使用   cookie-parser中间件,并希望在cookie中提取JWT   可以使用以下函数作为jwtFromRequest的参数   选项:

function cookieExtractor(req) {
    var token = null;
    if (req && req.cookies)
    {
        token = req.cookies.tokenName;
    }
    return token;
};

passport.use(
    new JwtStrategy({
        jwtFromRequest: cookieExtractor,
        secretOrKey: sails.config.jwtSettings.secret,
        issuer: sails.config.jwtSettings.issuer,
        audience: sails.config.jwtSettings.audience,
        passReqToCallback: false
    },
    function (payload, next) {
        var user = payload.user;
        return next(null, user, {});
    }));

最后但并非最不重要的是,如果您要使用cookie,则需要实施CSRF安全性,这里是您将使用拦截器的地方。首先,您需要告诉您的sails项目您将在config / csrf.js中使用csrf标记:

module.exports.csrf = true;

然后你可以在这里使用一个非常好的包来拦截你的ajax请求并发送csrf tokens和 https://github.com/aditzel/spring-security-csrf-token-interceptor。但是需要稍微调整才能使用sails:在spring-security-csrf-token-interceptor.js文件中搜索此行

this.token = xhr.getResponseHeader(this.settings.csrfTokenHeader);

并用以下两行代替:

var jsonResponse = JSON.parse(xhr.responseText);
                    this.token = jsonResponse._csrf;

这是你如何配置包用于帆的功能:

angapp.config(function(csrfProvider) {
    // optional configurations
    csrfProvider.config({
        url: '/csrfToken',
        csrfHttpType: 'get',
        httpTypes: ['HEAD', 'PUT', 'POST', 'DELETE'] //CSRF token will be added only to these method types
    });
});

注意:对于传统的视图表单,请阅读config / csrf.js文件中的注释。

还有一件事,因为您使用无状态jwt身份验证,您将需要存储两个cookie:一个用于身份验证并保存用户ID,如上所述,另一个用于存储将在前面查看时使用的用户信息结束并从后端更新

updateUserInfoCookie: function (res, user) {
        res.cookie('user', user.toJSON(), { secure: res.connection.encrypted ? true : false, maxAge: sails.config.jwtSettings.expiresIn * 1000, signed: true, httpOnly: true });
    },
    getCurrUserInfo: function(req){
        return req.signedCookies.user;
    }

希望这一点很清楚,对某人有帮助。

资源:https://stormpath.com/blog/build-secure-user-interfaces-using-jwts/