gpt4 book ai didi

javascript - 使用 JWT 在 React 上保护路由

转载 作者:行者123 更新时间:2023-12-04 17:22:50 26 4
gpt4 key购买 nike

我正在尝试为我的 React 项目创建 protected 路由,在后端我有 NodeJS。我看了很多例子,他们使用 localStorage 或“fakeAuth”,所以我没有真正获得我需要的正确信息,我遇到的主要问题是,当我登录时,我应该如何保存我登录的信息ATM,以便我的前端部分可以看到。

在我的 PrivateRoute 组件中,我需要有描述我的统计信息的 bool 值(是否登录),但我真的不明白我应该如何从我的后端“提取”该信息我的 PrivateRoute 组件:( bool 值应该代替 {{???????????????}} )

import React from "react";
import { Route, Redirect } from "react-router-dom";
import {authentication} from "./login.component"
import axios from 'axios';
export const PrivateRoute = ({ component: Component, ...rest}) => (
<Route
{...rest}
render={props =>
{{??????????????}} ? (
<Component {...props} />
) : (
<Redirect
to={{
pathname: "/login",
state: { from: props.location }
}}
/>
)
}
/>
);

这是我的登录组件:

import React, { useState } from 'react';
import axios from 'axios';
const Login = () => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const onChangeUsername = (e) => {
setUsername(e.target.value);
};
const onChangePassword= (e) => {
setPassword(e.target.value);
};
const onSubmit = async (e) => {
const user = {
username: username,
password: password
};
e.preventDefault();
await axios.post('http://localhost:5000/users/login', user);
};
return (
<div className="Login">
<h2>Traffic scan admin panel</h2>
<div className="LoginInfo-Logins">
<form>
<input type="text"
required
className=""
value={username}
onChange={onChangeUsername}
placeholder="Username*"
/>
<input type="text"
required
className=""
value={password}
onChange={onChangePassword}
placeholder="Password*"
/>
</form>
</div>
<button onClick={onSubmit}>SIGN IN</button>
</div>
)
}
export default Login;

这是我的后端部分:

require('dotenv').config();

const router = require('express').Router();
const Users = require('../models/user.model');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

router.route('/').get(authenticateToken, async (req, res) => {
const user = await Users.findOne({username: req.body.username});
if(!user) throw Error('User do not exist')
res.json(user)
});

router.route('/add').post(async (req, res) => {
try {
const hashedPassword = await bcrypt.hash(req.body.password, 10); // 10 is const salt = await bcrypt.genSalt/*10 is default*/);
const email = req.body.email;
const username = req.body.username;
const password = hashedPassword;
const IP = req.connection.remoteAddress;
const newUser = new Users({
email,
username,
password,
IP
});
newUser.save()
.then(() => res.json('User added!'))
.catch(err => res.status(400).json('Error: ' + err));
} catch {
res.status(500).send()
}
});
router.route('/login').post(async (req, res) => {
const user = await Users.findOne({username: req.body.username});
if(!user) throw Error('Password or Username')
if(await bcrypt.compare(req.body.password, user.password)) {
const accessToken = jwt.sign(user.toJSON(), process.env.ACCESS_TOKEN_SECRET, {expiresIn: 604800});
res.json({ accessToken: accessToken });
} else throw Error('Password or Username is incorrect');

});
function authenticateToken (req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if(token == null) return res.sendStatus(401);

jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, user)=>{
if(err) return res.send(403);
req.user = user;
next();
})
}
module.exports = router;

也许有人可以帮助我,关于如何做的任何建议、教程、示例都会有所帮助。

最佳答案

大多数教程都使用 localStoragecookie,因为您希望即使在用户刷新页面后也能保留登录状态,这样他们就不必每次都要重新登录。但要回答您的问题,您可以这样做:

import React, { useState } from "react";
import { Route, Redirect, BrowserRouter } from "react-router-dom";
import "./style.css";
import axios from "axios";

function yourLoginPostApi() {
return new Promise(r => setTimeout(() => r(true), 1000));
}

function Login({ onSuccess }) {
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
let [loading, setLoading] = useState(false);
const onChangeUsername = e => {
setUsername(e.target.value);
};
const onChangePassword = e => {
setPassword(e.target.value);
};
const onSubmit = async e => {
const user = {
username: username,
password: password
};
e.preventDefault();
setLoading(true);
// Uncomment this line and remove the next one since it's a fake api call
// let response = await axios.post("http://localhost:5000/users/login", user);
let response = await yourLoginPostApi();
setLoading(false);
onSuccess(response);
};
return (
<div className="Login">
<h2>Traffic scan admin panel</h2>
<div className="LoginInfo-Logins">
<form>
<input
type="text"
required
className=""
value={username}
onChange={onChangeUsername}
placeholder="Username*"
/>
<input
type="text"
required
className=""
value={password}
onChange={onChangePassword}
placeholder="Password*"
/>
</form>
</div>
<button onClick={onSubmit}>SIGN IN</button>
<div>{loading && "Please wait..."}</div>
</div>
);
}

function PrivateRoute({ children }) {
let [loggedIn, setLoggedIn] = useState(false);
return loggedIn ? (
<div>
{children}
<button onClick={() => setLoggedIn(false)}>log out</button>
</div>
) : (
<Login onSuccess={() => setLoggedIn(true)} />
);
}

export default function App() {
return (
<BrowserRouter>
<PrivateRoute>
<div>Stuff only a logged in user should see</div>
</PrivateRoute>
</BrowserRouter>
);
}

你可以看到 demo on stackblitz

关于javascript - 使用 JWT 在 React 上保护路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65156405/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com