javascript - 如何使用护照检查 react 组件上的isAuthenticated

标签 javascript reactjs components passport-local

我无法弄清楚如何从我所在的地方继续前进。现在我正在运行该应用程序,因此您可以注册并登录,但我希望能够通过删除导航中的注册登录并将其更改为注销来检查他们是否已登录。我四处搜索,但找不到任何人能够帮助我或指出正确方向的任何东西?

这是我的路线:

let express = require("express");
let router = express.Router();
let passport = require("passport");
let LocalStrategy = require("passport-local").Strategy;

let User = require("../../models/User");

// Register User
router.post("/register", function(req, res) {
  let email = req.body.email;
  let name = req.body.name;
  let phonenumber = req.body.phonenumber;
  let password = req.body.password;

  if (!name) {
    console.log("Errors");
  } else {
    //checking for email and username are already taken
    User.findOne(
      {
        email: {
          $regex: "^" + email + "\\b",
          $options: "i"
        }
      },
      function(err, mail) {
        if (mail) {
          res.render("register", {
            mail: mail
          });
        } else {
          let newUser = new User({
            name: name,
            email: email,
            phonenumber: phonenumber,
            password: password
          });

          User.createUser(newUser, function(err, user) {
            if (err) throw err;
            console.log(user);
          });

          req.flash("success_msg", "You are registered and can now login");
          res.redirect("/users/login");
        }
      }
    );
  }
});

passport.use(
  new LocalStrategy(
    {
      usernameField: "email"
    },
    function(username, password, done) {
      User.getUserByUsername(username, function(err, user) {
        if (err) throw err;
        if (!user) {
          return done(null, false, { message: "Unknown User" });
        }

        User.comparePassword(password, user.password, function(err, isMatch) {
          if (err) throw err;
          if (isMatch) {
            return done(null, user);
          } else {
            return done(null, false, {
              message: "Invalid password"
            });
          }
        });
      });
    }
  )
);

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.getUserById(id, function(err, user) {
    done(err, user);
  });
});

router.post(
  "/login",
  passport.authenticate("local", {
    successRedirect: "/YOU_DID_IT_SCRUB",
    failureRedirect: "/YOU_FAILED_SCRUB",
    failureFlash: true
  }),
  function(req, res) {}
);

module.exports = router;

这是我要显示登录注销按钮的组件

import React, { Component } from "react";
import {
  Navbar,
  NavbarBrand,
  NavbarItem,
  NavbarEnd,
  Modal,
  ModalCard,
  ModalCardTitle,
  ModalBackground,
  ModalCardFooter,
  ModalCardHeader,
  Delete,
  ModalCardBody
} from "bloomer";
import { Link } from "react-router-dom";
import StepZilla from "react-stepzilla";
import "bulma/css/bulma.css";
import "./Nav.css";
import pad from "./pad.png";
import modal from "./modal.svg";
import { SignUpModal } from "./SignUpModal";
import { LoginModal } from "./LoginModal";
import { MemberType } from "./MemberType";
import API from "../../utils/API";

const padLogo = { image: `url(${pad})` };
const steps = [
  { name: "Step 1", component: <MemberType /> },
  { name: "Step 2", component: <SignUpModal /> }
];

const modalBG = { backgroundImage: `url(${modal})` };

export class Nav extends Component {
  state = {
    modal: "",
    login: ""
  };

  modalOpen = () => {
    this.setState({ modal: "is-active" });
  };

  loginOpen = () => {
    this.setState({ login: "is-active" });
  };

  modalClose = () => {
    this.setState({
      modal: "",
      login: ""
    });
  };

  render() {
    return (
      <Navbar className="navbar">
        <NavbarBrand>
          <NavbarItem className="nav-logo-item">
            <img src={pad} />
          </NavbarItem>
          <NavbarItem>
            <Link to={"/"}>
              <p className="nav-title">Lilypad Rentals</p>
            </Link>
          </NavbarItem>
        </NavbarBrand>
        <NavbarEnd>
          <NavbarItem>
            <Link to={"/property"}>
              <p>Property</p>
            </Link>
          </NavbarItem>
          <NavbarItem>
            <Link to={"/results"}>
              <p>Results</p>
            </Link>
          </NavbarItem>
          <NavbarItem>
            <Link to={"/manager"}>
              <p>Property Form</p>
            </Link>
          </NavbarItem>
          <NavbarItem href="#">
            <p>Create Listing</p>
          </NavbarItem>
          <NavbarItem href="#" onClick={this.loginOpen}>
            <p>Log in</p>
          </NavbarItem>
          <NavbarItem href="#" onClick={this.modalOpen}>
            <p>Sign Up</p>
          </NavbarItem>
        </NavbarEnd>

        <div className="signup-modal">
          <Modal className={this.state.modal}>
            <ModalBackground />
            <ModalCard style={modalBG}>
              <ModalCardBody>
                <Delete onClick={this.modalClose} />

                <div className="step-progress">
                  <StepZilla
                    steps={steps}
                    showSteps={false}
                    nextButtonCls="button is-medium is-primary"
                    backButtonCls="button is-medium is-primary"
                  />
                </div>
              </ModalCardBody>
            </ModalCard>
          </Modal>
        </div>

        <div className="login-modal">
          <Modal className={this.state.login}>
            <ModalBackground />
            <ModalCard>
              <ModalCardHeader>
                <ModalCardTitle />
                <Delete onClick={this.modalClose} />
              </ModalCardHeader>
              <LoginModal />
              <ModalCardFooter hasTextAlign="centered">
                <p>
                  Already have an account? <Link to={""}>Log In</Link> .
                </p>
              </ModalCardFooter>
            </ModalCard>
          </Modal>
        </div>
      </Navbar>
    );
  }
}

最佳答案

如果身份验证成功,Passport 会创建一个 req.user 对象。您可以使用它来确定用户是否已登录。

If authentication succeeds, the next handler will be invoked and the req.user property will be set to the authenticated user - http://www.passportjs.org/docs/authenticate/

在继续之前,您必须设置 cookie-parser middleware在您的 Express 服务器上。

...
import cookieParser from 'cookie-parser';

app.use(cookieParser({secret: 'mySecret'}));
...

之后,您需要在成功回调中自己创建一个已签名的 cookie。

...
router.post(
  "/login",
  passport.authenticate("local", {
     successRedirect: "/YOU_DID_IT_SCRUB",
     failureRedirect: "/YOU_FAILED_SCRUB",
     failureFlash: true
  }),
  function(req, res) {
     // if this gets called then authentication was successful
     res.cookie('session', req.user.id, { secure: true, signed: true, expires: new Date(Date.now() + 3600) });
  });

我建议使用 react-cookie在客户端设置/获取 cookie。要解析签名的 cookie,只需 import cookieParser from 'cookie-parser' 并在 React 组件中使用 cookieParser.signedCookie() 方法解析签名的 cookie 并确认它客户端未被篡改。

res.cookie reference

关于javascript - 如何使用护照检查 react 组件上的isAuthenticated,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51517716/

相关文章:

javascript - 使用 Vue JS 将 props 从不同的路由发送到同一组件

.net - COM+ 组件由 C# 中的 Windows 服务托管,用于控制外部设备

javascript - 如何在主函数中返回 const 或函数

javascript - 旋转椭圆形 SVG 对象

javascript - Azure:Web 应用程序 - 列出已部署的 Nodejs 应用程序中的应用程序设置

javascript - React 和 Redux 应用程序设计

reactjs - 不断收到警告 : Invalid DOM property `autocomplete` . 您的意思是 `autoComplete` 吗?

javascript - 如何从javascript中的对象中删除时间?

reactjs - 变换上的布局动画

delphi - 从阻塞套接字更改为非阻塞套接字有什么好处?