如何使用Reactjs从受保护的路由获取数据

时间:2019-07-17 15:50:33

标签: node.js reactjs express jwt

我要实现什么目标?

我正试图从受保护的路由/api/getUser访问数据,但是我正在使用jwt令牌来保护在每个受保护的路由中都经过验证的路由。我已经测试了这些路由,并使用Postman将令牌传递给了该受保护的路由,它似乎工作正常。当我尝试使数据显示在名为Profile的组件的客户端上时,我在控制台中收到状态401错误的请求,并且显示“拒绝访问。未提供JWT”。这是从我的中间件检索的,中间件验证了每个路由,这使我认为令牌没有发送到客户端。

到目前为止我所知道的

我知道您可以使用cookie和localstorage,但是我将使用localstorage,因为这将是本机移动应用程序,而Reactjs也使用localstorage。我还在网上看到,我可以先将jwt令牌存储为cookie,然后再将cookie存储在localstorage中。

邮递员测试/api/getUser

我将标题设置如下

Content-type : application/json

x-auth-token : Contains my jwt token

结果如下。

{
    "id": 1,
    "first_name": "test1",
    "last_name": "test2",
    "email": "test@outlook.com",
    "password": "$2b$10$PbYRQf3uH52ErBiTUm.e.OliFSH9aDrOEpTeA0oj/aID3XaP/GxH6",
    "createdAt": "2019-07-17",
    "updatedAt": "2019-07-17"
}

/ api / authenticate

router.post('/authenticate', (req, res) => {
  User.findOne({
    where: {
      email: req.body.email
    }
  }).then(user => {
    if (user) {
      if (bcrypt.compareSync(req.body.password, user.password)) {
        const payload = {
          id: user.id,
          name: user.first_name
        };
        var token = jwt.sign(payload, config.get('secret'), {
          expiresIn: 1440 
        });

        res.send({
          message: 'authentication done ',
          token: token,
          user: user.toJSON()
        });

        console.log(token);
        console.log('Successful Login');
        console.log(user.first_name);
      } else {
        res.json({ message: 'please check your password !' });
        console.log('incorrect password');
      }
    } else {
      res.json({ message: 'user not found !' });
      console.log('user cannot be found');
    }
  });
});

/ api / GetUser

//This finds the authenticated user
router.get('/getUser', checkAuth, async (req, res) => {
  const user = await User.findOne({
    user: req.user.id
  });

  if (!user) {
    return res.status(404).send('Cannot find this user');
  }
  res.status(200).json(user);
});

反应登录组件

import React, { Component } from 'react';

class Login extends Component {
  constructor() {
    super();
    this.state = {
      email: '',
      password: '',
      errors: {}
    };

    this.onChange = this.onChange.bind(this);
    this.onSubmit = this.onSubmit.bind(this);
  }

  onChange(e) {
    this.setState({ [e.target.name]: e.target.value });
  }
  onSubmit(e) {
    e.preventDefault();

    const user = {
      email: this.state.email,
      password: this.state.password
    };


    fetch('http://localhost:5000/api/authenticate', {
      method: 'POST', // or 'PUT'
      body: JSON.stringify(user), // data can be `string` or {object}!
      headers: {
        'Content-Type': 'application/json'
        // Authorization: 'Bearer ' + token
      }
    });
  }

  render() {
    return (
      <div className='container'>
        <div className='row'>
          <div className='col-md-6 mt-5 mx-auto'>
            <form noValidate onSubmit={this.onSubmit}>
              <h1 className='h3 mb-3 font-weight-normal'>Please sign in</h1>
              <div className='form-group'>
                <label htmlFor='email'>Email address</label>
                <input
                  type='email'
                  className='form-control'
                  name='email'
                  placeholder='Enter email'
                  value={this.state.email}
                  onChange={this.onChange}
                />
              </div>
              <div className='form-group'>
                <label htmlFor='password'>Password</label>
                <input
                  type='password'
                  className='form-control'
                  name='password'
                  placeholder='Password'
                  value={this.state.password}
                  onChange={this.onChange}
                />
              </div>
              <button
                type='submit'
                className='btn btn-lg btn-primary btn-block'
              >
                Sign in
              </button>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

export default Login;

反应配置文件组件

注意:这只是从https://reactjs.org/docs/faq-ajax.html粘贴而来,因为这就是我试图完成此任务的方式。

class Profile extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      error: null,
      isLoaded: false,
      items: []
    };
  }

  componentDidMount() {
    fetch("https://localhost:5000/api/getUser")
      .then(res => res.json())
      .then(
        (result) => {
          this.setState({
            isLoaded: true,
            items: result.items
          });
        },
        // Note: it's important to handle errors here
        // instead of a catch() block so that we don't swallow
        // exceptions from actual bugs in components.
        (error) => {
          this.setState({
            isLoaded: true,
            error
          });
        }
      )
  }

  render() {
    const { error, isLoaded, items } = this.state;
    if (error) {
      return <div>Error: {error.message}</div>;
    } else if (!isLoaded) {
      return <div>Loading...</div>;
    } else {
      return (
        <ul>
          {items.map(item => (
            <li key={item.name}>
              {item.name} {item.price}
            </li>
          ))}
        </ul>
      );
    }
  }
}

0 个答案:

没有答案