0

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

我是新手,但这是我的代码:在网页上,用户必须先登录。我从我的 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);
    }

在这个过程中,我可以在我的浏览器中的响应选项卡中看到“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. 如何在后端访问它?

谢谢你。

4

1 回答 1

0

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

我的 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 My 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 上设置了一组不同的选项,但没有一个对我有用。祝你有美好的一天。神速。

于 2021-06-10T13:11:23.370 回答