http-only cookie + token:双重工作?

Posted

技术标签:

【中文标题】http-only cookie + token:双重工作?【英文标题】:http-only cookie + token : double job? 【发布时间】:2019-06-12 03:05:16 【问题描述】:

亲爱的,

我正在尝试了解如何使用服务器发送的仅 hhtp cookie 在客户端管理身份验证。

我不明白的是,由于前端无法访问仅HTTP cookie,那么前端如何知道用户(仍然)经过身份验证?

到目前为止,唯一的解决方案是在身份验证成功时向客户端发送令牌。并将此令牌保存在客户端创建的第二个 cookie 中。

但在我看来,我做了两次相同的工作。

1- 在服务器端管理仅 HTTP 的 cookie,尤其是过期日期 2- 在客户端也管理第二个 cookie 的到期日期。

如何避免这种情况?我想基于 HTTP only server cookie 管理客户端的身份验证。如果有服务器cookie,则继续,否则重定向到登录页面。

我在服务器端使用 node/express 并对客户端做出反应。会话存储在redis中,双方都是HTTPS使用证书。

感谢

【问题讨论】:

【参考方案1】:

您不需要存储另一个 cookie。 我想您在端点上使用基于令牌的身份验证,例如。智威汤逊。然后你想想这个场景:

    用户将用户名/密码发送到服务器。 检查用户凭据,如果有效,则使用令牌创建仅限 http 的 cookie
    const user = await getUser( where:  email  );

    const valid = await bcrypt.compare(password, user.password);
    if (!valid) 
      throw new UserInputError('Form Arguments invalid', 
        invalidArgs: 
          'password': 'Invalid password!',
        ,
      );
    

    const token = jwt.sign( userId: user.id , process.env.APP_SECRET);
    /
    res.cookie('token', token, 
      httpOnly: true,
      maxAge: 1000 * 60 * 60 * 24 * 365,
    );

    编写 auth 中间件,将 userId 放到 req 中,以便将来请求访问
const jwt = require('jsonwebtoken');
const  AuthenticationError  = require('apollo-server');

module.exports = async function(req, res, next) 
  const  token  = req.cookies;

  if (token) 
    try 
      const  userId  = jwt.verify(token, process.env.APP_SECRET);

      if (!userId) return next();
      req.userId = userId;

     catch (e) 
      console.log(e);
    
  

  next();
;
    检查每个请求的用户 ID。如果没有userId,则用户没有登录
  if (!req.userId) 
     throw new AuthenticationError('Log in!');
   
    如果用户的令牌无效/过期,您将收到 AuthenticationError。抓住它并重定向到登录页面。 如果您的 UI 依赖于用户状态,您可以创建易于使用的组件(我正在使用 React)来检查它。

用户组件:

import  Query  from 'react-apollo';
import gql from 'graphql-tag';
import PropTypes from 'prop-types';

const CURRENT_USER_QUERY = gql`
  query CURRENT_USER_QUERY 
    me 
      userId
      firstName
      lastName
      profilePictureUrl
    
  
`;

const User = props => (
  <Query ...props query=CURRENT_USER_QUERY fetchPolicy='cache-first'>
    payload => props.children(payload)
  </Query>
);

User.propTypes = 
  children: PropTypes.func.isRequired,
;

export default User;

如果我们从服务器获取me对象,你知道,有一个登录的用户,所以你可以根据用户的状态进行渲染:

import  Link  from 'react-router-dom';
import React from 'react';

<User>
  ( loading, error, data:  me  ) => 
    if (loading || error || !me) return (
      <Button component=Link to='/login'>Login</Button>
    );
    if(me) return (
      <Button component=Link to='/dashboard'>Go to dashboard</Button>
    )
  
</User>

【讨论】:

非常感谢,这正是我的想法。我要在 react 中创建一个 HOC Auth。 大家好,你们有这种实现的回购吗? 不幸的是我没有公开的回购。但请随时提出您的问题。

以上是关于http-only cookie + token:双重工作?的主要内容,如果未能解决你的问题,请参考以下文章

Tomcat 7 sessionid cookie 禁用 http-only 和安全

前端随心记---------HTTP之HTTP-only

利用HTTP-only Cookie缓解XSS之痛

如果用于认证的JWT令牌保存在HTTP-Only cookie中,你如何从cookie中读取它,以便我可以在请求头中包含它?

token储存和安全问题

如果用于身份验证的 JWT 令牌保存在 HTTP-Only cookie 中,您如何从 cookie 中读取它以便我可以将其包含在请求标头中?