【问题标题】:How to Implement Private Route with JWT Token in React如何在 React 中使用 JWT 令牌实现私有路由
【发布时间】:2020-01-10 09:44:49
【问题描述】:

我只为经过身份验证的用户设置仪表板。如何设置我的前端以从后端使用 jwt 访问私有路由?

这是登录的后端流程

const knex = require('../../../../database');
const path = require('path');
const jwt = require('jsonwebtoken');

function getUser(email, password) {
  return knex('admin_account')
    .select('email')
    .where({
      email,
      password
    }).first();
}

// app/models/user.js
const signin = async (req, res) => {
  try {
    const email = req.body.email;
    const password = req.body.password;
    if (!email || !password) {
      return res.status(400)
        .json({
          success: false,
          data: {
            error: "Email and password cannot be empty"
          },
        });
    }
    const result = await getUser(email, password)
    if (!result) {
      return res.status(404)
        .json({
          success: false,
          data: {
            error: "User tidak ditemukan, masukan Email dan Password-mu dengan benar"
          },
        });
    }
    return res.status(200).json({
      status: 'success',
      data: jwt.sign({
        role: 'admin',
        email
      }, process.env.SECRET)
    });
  } catch (error) {
    console.error({
      error: error.message
    });
    return res.status(400)
      .json({
        success: false,
        data: {
          error: JSON.stringify(error.message)
        },
      });
  }
}
module.exports = signin

这是登录和应用的前端

class Login extends React.Component {
  state = initialState

  handleSubmit = input => {
    input.preventDefault();
    const formData = new FormData();

    if (this.formisValid(this.state)) {
      this.setState({ errors: [], loading: true });
      formData.set('email', this.state.email)
      formData.set('password', this.state.password)

      axios({
        method: 'POST',
        url: config.endpoint + '/api/v1/admin',
        data: formData,
        config: { headers: {'Content-Type': 'multipart/form-data' }}
      })
      .then( response => response.json())
      .then((response) => {
        if (!response.error) {
          this.setState({ 
            initialState,
            submit: true
          });
          this.setState({ loading: false});
          console.log('User Login', response)
          this.props.history.push('/admin/dashboard');
        }


      }).catch((errors) => {
        // ? Show to user that request is failed
        this.setState({ errors: [errors] })
        this.setState({ loading: false });
        console.log('User not found, login failed', errors)
      });
    }
  };

  handleInputError = (errors, inputName) => {
      ...
  };

  render() {
    ...

    return (
        ...
        );
  }
}

export default Login;
class App extends Component {

  render() {
    return (
      <Router>
        <div>
          {/*This is the function to Route to Page (via switch)*/}
          <Switch>
            <Route exact path="/" component={Home} />
            <Route exact path="/login/admin" component={Login} />
            ...
            <Route exact path="/admin/dashboard" component={Dashboard} />
          </Switch>
        </div>
      </Router>
    );
  }
}

登录过程运行顺利,但我不知道如何保留令牌并使用 jwt 使路由私有

非常感谢我的朋友,感谢您的帮助!

【问题讨论】:

    标签: reactjs authentication react-router express-jwt jwt-auth


    【解决方案1】:

    我不确定我是否 100% 理解您的问题。如果我理解正确,您会尝试阻止某些用户在没有令牌(已断开连接)的情况下访问某个位置。

    在我的客户端界面中,我使用上下文来管理令牌并在组件之间共享它。

    App.js 看起来像这样。

    const App = () => {
      return (
        <TokenProvider>
          <div className="App">
            <RouteComponent />
          </div>
        </TokenProvider>
      )
    };
    
    const RouteComponent = () => {
      const { token } = useContext(TokenContext);
    
      return (
        <>
          {token ? (
            <Switch>
              ...Private routes
            </Switch>
          ) : (
            <Switch>
              ...Public routes
            </Switch>
          )}
       </>
      )
    };
    

    为确保用户不会访问不可用的位置,您将重定向设置为登录页面作为示例。

    希望对你有帮助,如果我犯了错误,我很抱歉。

    注意:这是基于我的经验,我并不是说这是一个好方法,但就我而言,它可以解决问题。

    【讨论】:

      猜你喜欢
      • 2020-11-18
      • 1970-01-01
      • 2020-11-17
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 2019-08-27
      • 2022-01-17
      • 2020-10-01
      相关资源
      最近更新 更多