NodeJS 401 API授权

lsmd5eda  于 2023-06-22  发布在  Node.js
关注(0)|答案(1)|浏览(118)

我是新手,对react和Node.js有一点问题,希望大家能帮助我。我做了一些API,其中一些需要认证,其他的则不需要。在Postman中,当我验证一切正常时,我可以调用需要验证的API,没有任何问题。除了在我的前端,当我对我的LoginPage页面进行身份验证时,它工作得很好,但是当我尝试,例如,使用API创建一个项目(需要身份验证)时,我得到了401 Unauthorized,即使我登录了,所有需要身份验证的API也是如此。我不明白为什么
这是我的登录页面

import React, { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useDispatch } from 'react-redux';
import { setLoggedIn } from '../store';

const LoginPage = () => {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [showPassword, setShowPassword] = useState(false);
  const [error, setError] = useState('');
  const navigate = useNavigate();
  const dispatch = useDispatch();

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handlePasswordChange = (e) => {
    setPassword(e.target.value);
  };

  const togglePasswordVisibility = () => {
    setShowPassword(!showPassword);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();

    const formData = {
      email,
      password
    };

    try {
      const response = await fetch('http://localhost:5000/user/login', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(formData)
      });

      if (response.ok) {
        const data = await response.json();
        console.log(data.message);
        setError(data.message);
        dispatch(setLoggedIn(true)); // Mise à jour de l'état de connexion
      
        // Stocker les informations de l'utilisateur dans le localStorage
        localStorage.setItem('user', JSON.stringify(data.user));
      
        navigate(`${process.env.PUBLIC_URL}`);
        // Redirigez l'utilisateur vers la page d'accueil ici
      }
      
    } catch (error) {
      console.log(error.message);
      setError(error.message);
      // Traitez les erreurs d'exception ici
    }
  };

  return (
    <div className="container-fluid px-1 py-5 mx-auto">
      <div className="row d-flex justify-content-center">
        <div className="col-xl-7 col-lg-8 col-md-9 col-11 text-center">
          <div className="card" style={{ maxWidth: '400px', margin: '0 auto' }}>
            <h5 className="text-center mb-4">Login</h5>
            <form className="form-card" onSubmit={handleSubmit}>
              <div className="row justify-content-center text-center">
                <div className="form-group col-md-12 flex-column d-flex">
                  <label className="form-control-label px-3">Email<span className="text-danger"> *</span></label>
                  <input type="text" id="email" name="email" placeholder="Enter your email" value={email} onChange={handleEmailChange} />
                </div>
              </div>
              <div className="row justify-content-center text-center">
                <div className="form-group col-md-12 flex-column d-flex">
                  <label className="form-control-label px-3">Password<span className="text-danger"> *</span></label>
                  <div className="password-input-wrapper d-flex align-items-center">
                    <input type={showPassword ? 'text' : 'password'} id="password" name="password" placeholder="Enter your password" value={password} onChange={handlePasswordChange} className="form-control" />
                    <button type="button" id="togglePassword" className="toggle-password-btn" onClick={togglePasswordVisibility}>
                      <i className="fas fa-eye"></i>
                    </button>
                  </div>
                </div>
              </div>
              <div className="row justify-content-center">
                <div className="form-group col-md-12">
                  <button type="submit" className="btn-block btn-primary">Login</button>
                </div>
              </div>
            </form>
            {error && <div className="alert alert-info" role="alert">{error}</div>}
          </div>
        </div>
      </div>
    </div>
  );
};

export default LoginPage;

这是我的CreateProject

import React from 'react';
import HeaderOne from '../common/header/HeaderOne';
import Breadcrumb from '../common/breadcrumb/Breadcrumb';
import TeamDetailsContent from '../components/team-details/TeamDetailsContent';
import FooterOne from '../common/footer/FooterOne';

const CreateProject = () => {
    return (
        <>
            <HeaderOne />
            <Breadcrumb 
                heading="Créer un projet"
                currentPage="Create Project" 
            />
            <TeamDetailsContent />
            <FooterOne />
        </>
    )
}

export default CreateProject;

还有他的零件我去哪里取我的API

import React from 'react';
import { useNavigate } from 'react-router-dom';

export default class TeamDetailsContent extends React.Component {
  handleSubmit = (event) => {
    event.preventDefault();

    const formData = new FormData(event.target);

    // Récupérer les informations d'utilisateur du localStorage
    const user = JSON.parse(localStorage.getItem('user'));

    // Ajouter les informations d'email et de mot de passe à formData
    formData.append('email', user.email);
    formData.append('password', user.password);

    fetch('http://localhost:5000/project/create', {
      method: 'POST',
      body: formData,
      credentials: 'include',
    })
      .then((response) => response.json())
      .then((data) => {
        console.log(data); // Gérer la réponse de l'API ici
      })
      .catch((error) => {
        console.error('Error creating project:', error);
      });
  };

  render() {
    let publicUrl = process.env.PUBLIC_URL + '/';
    return (
      <>
        <section className="join-team">
          <div className="container">
            <div className="row">
              <div className="col-xl-6 col-lg-6">
                <div className="join-team__Left">
                  <div className="join-team__images">
                    <div className="row">
                      <div className="col-xl-6 col-lg-6 col-md-6">
                        <div className="join-team__img-single">
                          <img src={publicUrl + 'assets/images/team/join-team-img-1.jpg'} alt="" />
                        </div>
                      </div>
                      <div className="col-xl-6 col-lg-6 col-md-6">
                        <div className="join-team__img-single">
                          <img src={publicUrl + 'assets/images/team/join-team-img-2.jpg'} alt="" />
                        </div>
                      </div>
                    </div>
                  </div>
                  <div className="join-team__content">
                    <h3 className="join-team__title">Requirements</h3>
                    <p className="join-team__text">
                      Aliquam hendrerit a augue insu image pellentes que id erat quis sollicitud null mattis Ipsum is
                      simply dummy typesetting industry. Alienum phaedrum torquatos nec eu, vis detraxit periculis ex,
                      nihil expetendis in meifn pericula euripidis.
                    </p>
                    <ul className="list-unstyled join-team__points">
                      <li>Nsectetur cing do not elit.</li>
                      <li>Suspe ndisse suscipit sagittis in leo.</li>
                      <li>Entum estibulum dignissim lipsm posuere.</li>
                    </ul>
                    <div className="join-team__contact">
                      <p>
                        <a href="tel:1307776-0608" className="join-team__phone">
                          + 1 (307) 776-0608
                        </a>
                        <a href="mailto:needhelp@company.com" className="join-team__email">
                          needhelp@company.com
                        </a>
                      </p>
                    </div>
                  </div>
                </div>
              </div>
              <div className="col-xl-6 col-lg-6">
                <div className="join-team__right">
                  <form className="join-team__form" onSubmit={this.handleSubmit}>
                    <div className="row">
                      <div className="col-xl-12">
                        <div className="join-team__input">
                          <input type="text" placeholder="Nom du projet" name="title" />
                        </div>
                      </div>
                      <div className="col-xl-12">
                        <div className="join-team__input">
                          <textarea type="text" placeholder="Description du projet" name="description"></textarea>
                        </div>
                      </div>
                      <div className="col-xl-12">
                        <div className="join-team__input">
                          <input type="text" placeholder="Somme à atteindre" name="targetAmount" />
                        </div>
                      </div>
                      <div className="col-xl-12">
                        <div className="join-team__input">
                          <input type="text" placeholder="Nombre de jours" name="duration" />
                        </div>
                      </div>
                      <div className="col-xl-6">
                        <div className="join-team__input">
                          <input type="text" placeholder="Catégorie" name="category" />
                        </div>
                      </div>
                      <div className="col-xl-12">
                        <div className="join-team__input">
                          <input type="file" accept="image/*" name="coverPhoto" />
                        </div>
                      </div>
                      <div className="col-xl-12">
                        <div className="join-team__btn-box">
                          <button type="submit" className="thm-btn join-team__btn">
                            Créer le projet
                          </button>
                        </div>
                      </div>
                    </div>
                  </form>
                </div>
              </div>
            </div>
          </div>
        </section>
        {/* Join Team End */}
      </>
    );
  }
}

当我登录LoginPage时,我希望能够访问其他需要身份验证的API,因为在Postman上测试它们时,我就是这样登录的。

gkl3eglg

gkl3eglg1#

如果你想实现一个OAuth2,你应该考虑服务器和客户端之间通信的主键是token
当您调用OAuth2服务的登录API时,它会以简单的方式为您提供一个唯一的令牌,该令牌可用作未来API调用中的身份验证密钥。
因此,您应该获取该令牌并将其附加到每个请求的头部,以便在所有需要身份验证的API中检索数据。

fetch('http://localhost:5000/project/create', {
      method: 'POST',
      body: formData,
      credentials: 'include',
      headers: {
      'Authorization': 'Bearer ' + token,
     }
    })

相关问题