【问题标题】:Hide The Cookie in request and response objects在请求和响应对象中隐藏 Cookie
【发布时间】:2021-06-05 17:50:40
【问题描述】:

使用 Visual Studio Code、Angular、js 和 ts 有没有办法隐藏 cookie 值,所以你不能在 chrome 检查选项卡中“看到”它 see here

我是新手,但这是我的代码: 在网页上,用户必须先登录。 我从我的 userService 发送用户数据:

UserService.js file Front end

import { HttpClient } from '@angular/common/http';
...
login(user: User) {
    return this.http.post(`${this.URL}/login`, user);
}

我获取凭据并在后端创建一个像这样的 cookie:

UserControler.js file on the backend

exports.login = async (req, res) => {
     //I accsess the data like this
     //req.body.email
     //req.body.password
     
     // doing some validations, and create an encrypted token
     try {
        // I catch this on the front end
        res.cookie("access-token", token).json({
           token: token,
           data: user.email,
           message: "Successfully Logged In!"
         });
     } catch(e) {
        console.log(e.massage);
     }
}

我的登录组件开始了这个故事:

 import { UserService } from 'src/app/services/user/user.service';
 ....
 this.userService.login(user).subscribe(
    (res: any) => {
      this.token = res.token;
      this.userFirstName = res.data;
      this.successMessage = res['message'];
      
      // setting my new cookie
      document.cookie = this.token;
      // now every component can check the token with document.cookie
    },
    (error) => {
      console.log(error.error.message);
    }

在这个过程中,我可以在浏览器的响应标签see here中看到“cookie” 从这里开始,前端拥有令牌,理论上它应该在我发出的每个请求中自动发送它,而无需我明确添加它。这不起作用,我不知道为什么。

我尝试将其设置在标题中,如下所示:

 UserService.js Backend
 import{ HttpHeaders } from '@angular/common/http';
 ....
 getHeaderOptions(){
   const headers= new HttpHeaders()
   .set('content-type', 'application/json')
   .set('Access-Control-Allow-Origin', '*')
   .set('SetCookie', document.cookie); // here is my token in the Set-Cookie header

   return {"headers": headers};
}

myFunction(data: string) {
  return this.http.post(`${this.URL}/setUserPassword`, data, this.getHeaderOptions());
}

然后在后端我尝试像这样访问该标头: UserControle.js

exports.myFunction = async (req, res) => {
   token = "";
   if (req.header("Set-Cookie") != undefined) { 
      token = req.header("Set-Cookie");
      retVal = true;
   }  
}

我得到 req.header("Set-Cookie") 是未定义的,我无法打印 req 对象的值,我得到 [Object object]

所以我需要以下问题的答案:

  1. 有没有办法从 beckend 隐藏 cookie 中的令牌?
  2. 如何在我提出的每个请求中发送它?
  3. 如何在后端访问它?

谢谢。

【问题讨论】:

    标签: javascript cookies


    【解决方案1】:

    有点晚了,我现在明白了。 这对我有用:

    我的 BE server.js 文件:

    const express = require("express");
    const morgan = require("morgan");
    const dotenv = require("dotenv");
    const db = require("./database");
    const routes = require("./routes");
    const cookieParser = require("cookie-parser"); // need to parse the cookies
    
    const PORT = process.env.PORT || 1225;
    const app = express();
    
    app.use(cookieParser());
    app.use(express.json());
    app.use(express.urlencoded({ extended: true }));
    
    app.use(morgan("common"));
    
    dotenv.config();
    
    app.use("/api", routes); // for multiple controller handling
    

    从那里它以我的路由器索引文件为目标

    const express = require("express");
    const router = express.Router();
    const validateToken = require("../middlewares/Auth");
    const error = require("../middlewares/Error");
    const cookieParser = require("cookie-parser");
    
    router.use(cookieParser());
    
    router.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "http://localhost:4200");
    res.header("Access-Control-Allow-Credentials", "true"); //THIS IS IMPORTANT
    res.header("Access-Control-Allow-Methods", "PATCH, POST, PUT, GET, 
    OPTIONS, DELETE");//THIS IS IMPORTANT
    res.header("Access-Control-Max-Age", "3600");
    res.header("Access-Control-Expose-Headers", "X-number-of-elements,X-total-pages,X-total-elements,X-page-number");
    res.header("Access-Control-Allow-Headers", "X-Requested-With,authorization," + " Content-Type,Authorization,client_id,client_secret,grant_type,refresh_token,access_token," + "X-number-of-elements,X-total-pages,X-total-elements,X-page-number");
    
    if (req.method === "OPTIONS") {
      res.header("Access-Control-Allow-Methods", "PUT, POST, DELETE, GET, PATCH"); // THIS IS IMPORTANT
      return res.status(200).json({});
    }
    next();
    });
    
    //index files for my controller
    const clientRoutes  = require("./client/index");
    
    // insert authentication procedure (validateToken.auth), to check for jwt token in the cookies
    router.use("/clients", validateToken.auth, clientRoutes);
    
    router.use(error);
    
    router.get("/", (req, res) => {
      res.json({
        message: "?",
      });
    });
    
    module.exports = router;
    

    这里来自中间件的身份验证检查 jwt 我的 Auth.js 文件:

    const jwt = require("jsonwebtoken");
    
    /**
     * takes an request token, finds the header, searches for access_token,
     * json web token verifies it,
     * and checks if the token user credentials are the same as the given     validUser
     */
    const auth = (req, res, next) => {
    
      let token = req.cookies["access-token"]; // HERE USE THE NAME OF YOUR COOKIE
      retVal = false;
      email = "";
      errorMsg = "";
    
      // check if the cookie header contains our cookie 'access-token'
      if (token == undefined) {
        errorMsg = "No token found";
        return res.status(401).send({ status: 400, message: "No token found" });
      }
    
      try {
        // jwt will throw exception if something is wrong with the token
        jwt.verify(token.toString(), process.env.JWT_KEY); // YOU NEED TO HAVE A KEY TO CRIPT/DECRIPT
    
        // get jwt payload
        const decodedToken = jwt.decode(token.toString());
        // check the sub 
        if (decodedToken.sub != undefined) {
          email = decodedToken.sub;
        }
    
    
        // check if its expired
        if (decodedToken.exp < new Date().getTime()/1000)  { // I set a time to expire, its 1h from the login
          retVal = false;
          errorMsg = "Token Expired.";
        }
    
        // if we do anything in the last 10 mins of the token time
        // we will expand the time period for 1h
        let difference = decodedToken.exp - new Date().getTime()/1000;
        if (difference < 600) {// less then 10 mins to expire
        // create a new token
        let newToken = jwt.sign({ sub: email, exp:  decodedToken.exp + (60 * 60)}, process.env.JWT_KEY);
    
          const cookieOptions = { 
            httpOnly: false, 
            secure:false,
            path: "/"
          }
    
          // new cookie
          res.cookie("access-token", newToken, cookieOptions);
        }
    
        // attach email to req object to forward it to the next function
        req.email = decodedToken.sub;
        // tells the router to continue with the next function in line
        next();
    
      } catch (e) {
        console.error(e.message);
        retVal = false;
    
        return res.status(401).send({ status: 401, message: e.message });
      }
    }
    
    module.exports.auth = auth;
    

    之后一切正常。

    在 FE 上: 在我的 clientService.js 文件中:

    addClient(email: string, name: string, code: string) {
      return this.http.post(`${this.URL}/addClient`, { email: email, name: name, code: code }, withCredentials: true);   // options need to have withCredentials: true
    }
    

    这对我有用, 我希望这会对你有所帮助,我搜索了分配,大多数答案在 BE 和 FE 上设置了一组不同的选项,但没有一个对我有用。 祝你有美好的一天。 神速。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-16
      • 1970-01-01
      • 1970-01-01
      • 2013-11-11
      • 1970-01-01
      • 2017-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多