本地存储令牌问题

时间:2021-04-07 20:46:36

标签: javascript node.js reactjs jwt local-storage

所以这个问题我面临了很长一段时间。基本上在某种程度上注册用户工作。这就是正在发生的事情,当用户被创建并且我在开发工具/应用程序中显示 Auth 令牌并且我被推送到我应该的家时。

刷新页面时出现此错误 × Error: A cross-origin error was thrown. React doesn't have access to the actual error object in development. See https://reactjs.org/link/crossorigin-error for more information. 我可以通过清除 localStorage 来解决此问题。所以如果每次创建一个新用户,如果它想刷新页面,我每次都必须清除本地存储。完全不方便。

还有另一个错误,注销处理程序有问题,当我按下注销按钮时,它显示此错误 TypeError: Cannot read property 'push' of undefined 并指出错误位于 UserContext 中。我真的很感激一些帮助。

用户上下文

import React from "react";
import { useHistory } from "react-router-dom"
const UserContext = React.createContext();

function getUserFromLocalStorage() {
    return localStorage.getItem("authToken")
      ? JSON.parse(localStorage.getItem("authToken"))
      : { username: null, token: null };
  }

function UserProvider({ children }) {
  const [user, setUser] = React.useState(getUserFromLocalStorage());
  const routerHistory = useHistory()
  const logoutHandler = () =>{
    localStorage.removeItem("authToken");
    setUser(user);
    routerHistory.push("/")
  }
  return (
    <UserContext.Provider
      value={{ user, setUser, logoutHandler  }}
    >
      {children}
    </UserContext.Provider>
  );
}

export { UserContext, UserProvider };

登录

import React, { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
import { UserContext } from "../../context/user";


const Login = () => {
  const { user, setUser } = React.useContext(UserContext);
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [error, setError] = useState("");
  
  const history = useHistory()
  

  const loginHandler = async (e) => {
    e.preventDefault();
    
    const config = {
      header: {
        "Content-Type": "application/json",
      },
    };
    try {
      const { data } = await axios.post(
        "http://localhost:5000/api/auth/login",
        { email, password },
        config
      );
      user.authToken = data.token;
      setUser(user)
      history.push("/");
    } catch (error) {
      if (error.response) {
        setError(error.response.data.error);
      }
      setTimeout(() => {
         setError("");
      }, 5000);
    }
  };

  return (
    <div className="signin">
          <Link to='/'>
            <img src='/audible/logo.png' />
          </Link>  
      <form onSubmit={loginHandler} className="form__container">
        <h3>Sign in with your Amazon account</h3>
        {error && <span className="error__message">{error}</span>}
          <span className='labels'>Email </span>
          <input
           className="input__field"
            type="email"
            required
            id="email"
            onChange={(e) => setEmail(e.target.value)}
            value={email}
            tabIndex={1}
          />
          <span className='signin__forgot'>Password{" "}
            <Link className='links' to="/forgotpassword" >
              Forgot Password?
            </Link>
         </span> 
          <input
            className="input__field"
            type="password"
            required
            id="password"
            autoComplete="true"
            onChange={(e) => setPassword(e.target.value)}
            value={password}
            tabIndex={2}
          />
        <button type="submit" className="signin__btn">
          Sign In
        </button>
         <span className='new__sign'>New to Amazon? </span>
         <Link to="/register"> 
          <button className='signin__register'>
          Create your amazon account
          </button>
        </Link>
       
      </form>
    </div>
  );
};

export default Login;

注册

import { useState, } from "react";
import axios from "axios";
import { Link  } from "react-router-dom";
import { useHistory } from "react-router-dom"

const Register = () => {
  const [username, setUsername] = useState("");
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [confirmpassword, setConfirmPassword] = useState("");
  const [error, setError] = useState("");
  const routerHistory = useHistory()
  const registerHandler = async (e) => {
    e.preventDefault();
  
    const config = {
      header: {
        "Content-Type": "application/json",
      },
    };

    if (password !== confirmpassword) {
      setPassword("");
      setConfirmPassword("");
      setTimeout(() => {
        setError("");
      }, 5000);
      return setError("Passwords do not match");
    }

    try {
      const { data } = await axios.post(
        "http://localhost:5000/api/auth/register",
        {
          username,
          email,
          password,
        },       
        config
      );
    
      localStorage.setItem("authToken", data.token);

      routerHistory.push('/login')
    } catch (error) {
      if (error.response) {
        setError(error.response.data.error);
      }
      setTimeout(() => {
         setError("");
      }, 5000);
    }
  };

  return (
    <div className="signin">
      <Link to='/'>
        <img src='/audible/logo.png' />
      </Link>  
      <form onSubmit={registerHandler} className="form__container">
        <h3>Create account</h3>
        {error && <span className="error__message">{error}</span>}
          <span  className='labels'>Username</span>
          <input
            type="text"
            className="input__field"
            required
            id="name"          
            value={username}
            onChange={(e) => setUsername(e.target.value)}
          />
          <span  className='labels'>Email</span>
          <input
            type="email"
            className="input__field"
            required
            id="email"  
            value={email}
            onChange={(e) => setEmail(e.target.value)}
          /> 
          <span  className='labels'>Password</span>
          <input
            type="password"
            required
            id="password"
            className="input__field"
            autoComplete="true"
            placeholder="At least 6 characters"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
          <span  className='labels'>Re-enter password</span>
          <input
            type="password"
            required
            id="confirmpassword"
            className="input__field"
            autoComplete="true"
            value={confirmpassword}
            onChange={(e) => setConfirmPassword(e.target.value)}
          />   
        <button type="submit"  className="register__btn">
          Create your Amazon account
        </button>
        <span >
          Already have an account? <Link className='links' to="/login">Login</Link>
        </span>
      </form>
    </div>
  );
};

export default Register;

登录链接

import React from "react";
import { Link, useHistory } from "react-router-dom";
import { CartContext } from "../../context/cart";
import { UserContext } from "../../context/user";
export default function LoginLink() {
  const { user, logoutHandler } = React.useContext(UserContext);
  const { clearCart } = React.useContext(CartContext);
  if (user.authToken) {
    return (
      <button
        onClick={() => {
          logoutHandler();
          clearCart()
        }}
        className="login-btn"
        >
        logout
      </button>
    );
  }
  return <Link to="/login">Signin</Link>;
}

0 个答案:

没有答案