javascript - How to authentication React Front End with back-end Node.js Express-Sessions? - Stack Overflow

I'm moving away from using firestore auth to understand how to make my own authentication system.

I'm moving away from using firestore auth to understand how to make my own authentication system.

My goal:

  1. Create a react web app that lets user sign up and sign in .
  2. Authenticated users can operate on restAPI, which is NodeJS hooked up to Postgres.

I've watched a lot of tutorials. Most of them talk about express-sessions as as solution. However, when i tried it - these session cookie are only provided when my browser is on the express uri.

The issue is... On the front-end, when I send CRUD operation via fetch to my express api, my react-app do not get that cookie.

is what I'm doing the conventional way to handle authentication with backend server? How can i fix this?

EXPRESS:


require("dotenv").config();
const express = require("express");
const db = require("./db");
var session = require("express-session");
var pgSession = require("connect-pg-simple")(session);

const app = express(); //create an instance;
// :id url param.
app.use(
    session({
      store: new pgSession({ pool: db.pool }),
      secret: "secret",
      resave: false,
      saveUninitialized: false,
      cookie: { maxAge: 303 * 24 * 60 * 60 * 1000 }, //30days
    })
  );

app.use(function (req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, OPTIONS, PUT, PATCH, DELETE"
  );
  res.setHeader(
    "Access-Control-Allow-Headers",
    "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers,X-Access-Token,XKey,Authorization"
  );
  next();
});

app.use(express.json());

app.post("/addUser", async (req, res) => {
  try {
    const results = await db.query(
      "INSERT INTO USERS (email, password) values ($1, $2) returning *",
      [req.body.email, req.body.password]
    );
    console.log(results);
    req.session.isAuth = true;
    res.status(201).json({
      status: "success",
      data: {
        user: results.rows,
      },
    });

  } catch (err) {
    console.log(err);
  }
});

ReactJS


import React, { useEffect, useState } from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  Redirect,
} from "react-router-dom";
const App = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [authenticated, setAuthenticated] = useState(false);
  const onSubmit = (e) => {
    e.preventDefault();
    fetch("http://localhost:3006/addUser", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email: email, password: password }),
    })
      .then(function (response) {
        return response.json();
      })
      .then((response) => {
        console.log(response);
        setAuthenticated(true);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  return (
    <Router>
      <Switch>
        <router path="/" exact>
          <div>
            <form onSubmit={(e) => onSubmit(e)}>
              <label>email</label>
              <input
                name="email"
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
              ></input>
              <label>password</label>
              <input
                name="password"
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
              ></input>
              <input type="submit" value="submit"></input>
            </form>
          </div>
          {authenticated ? <Redirect to="/auth" /> : null}
        </router>
        <Route path="/auth" exact>
          Authenticated
        </Route>
      </Switch>
    </Router>
  );
};

export default App;

in React - after submitting the form, cookies didnt show up in the devtools.

I'm moving away from using firestore auth to understand how to make my own authentication system.

My goal:

  1. Create a react web app that lets user sign up and sign in .
  2. Authenticated users can operate on restAPI, which is NodeJS hooked up to Postgres.

I've watched a lot of tutorials. Most of them talk about express-sessions as as solution. However, when i tried it - these session cookie are only provided when my browser is on the express uri.

The issue is... On the front-end, when I send CRUD operation via fetch to my express api, my react-app do not get that cookie.

is what I'm doing the conventional way to handle authentication with backend server? How can i fix this?

EXPRESS:


require("dotenv").config();
const express = require("express");
const db = require("./db");
var session = require("express-session");
var pgSession = require("connect-pg-simple")(session);

const app = express(); //create an instance;
// :id url param.
app.use(
    session({
      store: new pgSession({ pool: db.pool }),
      secret: "secret",
      resave: false,
      saveUninitialized: false,
      cookie: { maxAge: 303 * 24 * 60 * 60 * 1000 }, //30days
    })
  );

app.use(function (req, res, next) {
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader(
    "Access-Control-Allow-Methods",
    "GET, POST, OPTIONS, PUT, PATCH, DELETE"
  );
  res.setHeader(
    "Access-Control-Allow-Headers",
    "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers,X-Access-Token,XKey,Authorization"
  );
  next();
});

app.use(express.json());

app.post("/addUser", async (req, res) => {
  try {
    const results = await db.query(
      "INSERT INTO USERS (email, password) values ($1, $2) returning *",
      [req.body.email, req.body.password]
    );
    console.log(results);
    req.session.isAuth = true;
    res.status(201).json({
      status: "success",
      data: {
        user: results.rows,
      },
    });

  } catch (err) {
    console.log(err);
  }
});

ReactJS


import React, { useEffect, useState } from "react";
import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link,
  Redirect,
} from "react-router-dom";
const App = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [authenticated, setAuthenticated] = useState(false);
  const onSubmit = (e) => {
    e.preventDefault();
    fetch("http://localhost:3006/addUser", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email: email, password: password }),
    })
      .then(function (response) {
        return response.json();
      })
      .then((response) => {
        console.log(response);
        setAuthenticated(true);
      })
      .catch((err) => {
        console.log(err);
      });
  };

  return (
    <Router>
      <Switch>
        <router path="/" exact>
          <div>
            <form onSubmit={(e) => onSubmit(e)}>
              <label>email</label>
              <input
                name="email"
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
              ></input>
              <label>password</label>
              <input
                name="password"
                type="password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
              ></input>
              <input type="submit" value="submit"></input>
            </form>
          </div>
          {authenticated ? <Redirect to="/auth" /> : null}
        </router>
        <Route path="/auth" exact>
          Authenticated
        </Route>
      </Switch>
    </Router>
  );
};

export default App;

in React - after submitting the form, cookies didnt show up in the devtools.

Share Improve this question edited May 20, 2021 at 2:45 cozycoder asked May 20, 2021 at 2:32 cozycodercozycoder 3413 silver badges14 bronze badges 2
  • Could you please share your server code and API URL example? – WebEXP0528 Commented May 20, 2021 at 2:37
  • yes, ive updated it. please take a look. thank you – cozycoder Commented May 20, 2021 at 2:46
Add a ment  | 

1 Answer 1

Reset to default 5
  1. In Server
  • Please enable cors(install cors library).
app.use(
  cors({
    origin: true,
    credentials: true,
    optionsSuccessStatus: 200
}))
  • Add session configuration.
app.use(
  session({
    key: 'sid',
    secret: Secret_String,
    resave: false,
    saveUninitialized: false,
    cookie: {
      path: '/',
      sameSite: 'none',
      httpOnly: true,
      secure: false,
      maxAge: 1000000000, // ten seconds, for testing
    },
    store: store, // postgres session store
  }),
);
  1. In Client, You have to use withcredentials option when calling API.
  • Chrome disabled set-cookie for different origin from 85.0 version. So, the set-cookie wont be work. You have to disable secure option in chrome. Please go to chrome://flags -> Cookies without SameSite must be secure -> disabled
  1. In your code
fetch("http://localhost:3006/addUser", {
      method: "POST",
      credentials: 'include',
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email: email, password: password }),
})

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745229605a4617617.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信