如何使用护照检查is组件上的isAuthenticated

时间:2018-07-25 11:25:24

标签: 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>
    );
  }
}

2 个答案:

答案 0 :(得分:1)

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

  

如果身份验证成功,则将调用下一个处理程序,并将req.user属性设置为已身份验证的用户-http://www.passportjs.org/docs/authenticate/

在继续进行操作之前,您必须在Express服务器上设置cookie-parser middleware

...
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。要仅通过import cookieParser from 'cookie-parser'解析签名的cookie,并在React组件中使用cookieParser.signedCookie()方法来解析签名的cookie,并确认它在客户端没有被篡改。

res.cookie reference

答案 1 :(得分:0)

在服务器端对用户进行身份验证之后,可以使用JSON Web Tokens创建带有用户信息的令牌,以发送到前端。

一旦有了,您就可以通过将令牌存储在本地存储中来轻松地在React中对用户进行身份验证或取消身份验证。这是一些简单步骤的示例:

考虑一个Auth.js文件

class Auth {

    static authenticateUser(token) {
        localStorage.setItem('token', token)
    }

    static isUserAuthenticated() {
        return localStorage.getItem('token') !== null
    }

    static deauthenticateUser() {
        localStorage.removeItem('token')
    }

    static getToken() {
        return localStorage.getItem('token')
    }
}

export default Auth

在现有的Nav.js组件中,检索从服务器端发送的令牌,然后您可以执行以下操作:

import Auth from './Auth'
export default class Nav extends Component {

    // authenticate user upon login
    isLoggedIn(token) {
        Auth.authenticateUser(token)
    }

    render() {
        if (Auth.isUserAuthenticated()) {
            return <NavbarItem>Log out</NavbarItem>
        } else {
            return <NavbarItem>Log in</NavbarItem>
        }
    }
}