javascript - 如何实现角色的值
问题描述
我正在制作这个 MERN RBAC 全栈应用程序,但在将角色分配给值时遇到了问题。我需要一个管理员和超级管理员。当我将值实现到前端时,什么也没有发生。我相信我在 userRouter.js 中需要一些东西,但我不知道是什么。谁能告诉我我做错了什么以及如何解决它?非常感谢。
用户路由器.js
const router = require("express").Router();
const User = require("../models/userModel");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
// router.get("/role", (req, res) => {
// const role = req.bodyrole;
// db.query(
// role,
// (err, result) => {
// if(err) {
// res.send({err:err})
// }
// }
// )
// })
// Read Users
router.get("/", (req, res) => {
User.find().exec((err, users) =>{
if(err) return res.status(400).json({ success: false, err });
return res.status(200).json({ success: true, users: users });
});
});
// Delete Users
router.delete("/delete/:id", (req, res) => {
User.findByIdAndRemove(req.params.id).exec((err, deleteItem) => {
if(err){
res.send(err);
}
return res.json(deleteItem);
})
})
// register
router.post("/", async (req, res) => {
try {
const { name, email, password, passwordVerify, role } = req.body;
// validation
if (!name || !email || !password || !passwordVerify || !role)
return res
.status(400)
.json({ errorMessage: "Please enter all required fields." });
if (password.length < 6)
return res.status(400).json({
errorMessage: "Please enter a password of at least 6 characters.",
});
if (password !== passwordVerify)
return res.status(400).json({
errorMessage: "Please enter the same password twice.",
});
const existingUser = await User.findOne({ email });
if (existingUser)
return res.status(400).json({
errorMessage: "An account with this email already exists.",
});
// hash the password
const salt = await bcrypt.genSalt();
const passwordHash = await bcrypt.hash(password, salt);
// save a new user account to the db
const newUser = new User({
name,
email,
passwordHash,
role
});
const savedUser = await newUser.save();
// sign the token
const token = jwt.sign(
{
user: savedUser._id,
},
process.env.JWT_SECRET
);
// send the token in a HTTP-only cookie
res
.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "none",
})
.send();
} catch (err) {
console.error(err);
res.status(500).send();
}
});
// log in
router.post("/login", async (req, res) => {
try {
const { email, password } = req.body;
// validate
if (!email || !password)
return res
.status(400)
.json({ errorMessage: "Please enter all required fields." });
const existingUser = await User.findOne({ email });
if (!existingUser)
return res.status(401).json({ errorMessage: "Wrong email or password." });
const passwordCorrect = await bcrypt.compare(
password,
existingUser.passwordHash
);
if (!passwordCorrect)
return res.status(401).json({ errorMessage: "Wrong email or password." });
// sign the token
const token = jwt.sign(
{
user: existingUser._id,
},
process.env.JWT_SECRET
);
// send the token in a HTTP-only cookie
res
.cookie("token", token, {
httpOnly: true,
secure: true,
sameSite: "none",
})
.send();
} catch (err) {
console.error(err);
res.status(500).send();
}
});
router.get("/logout", (req, res) => {
res
.cookie("token", "", {
httpOnly: true,
expires: new Date(0),
secure: true,
sameSite: "none",
})
.send();
});
router.get("/loggedIn", (req, res) => {
try {
const token = req.cookies.token;
if (!token) return res.json(false);
jwt.verify(token, process.env.JWT_SECRET);
res.send(true);
} catch (err) {
res.json(false);
}
});
module.exports = router;
用户模型.js
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: {type: String},
email: { type: String, required: true },
passwordHash: { type: String, required: true },
role: {type: String, enum: ["admin", "superadmin"]}
});
const User = mongoose.model("user", userSchema);
module.exports = User;
auth.js
import axios from "axios";
import React, { createContext, useEffect, useState } from "react";
const AuthContext = createContext();
function AuthContextProvider(props) {
const [loggedIn, setLoggedIn] = useState(undefined);
async function getLoggedIn() {
const loggedInRes = await axios.get("http://localhost:5000/auth/loggedIn");
// const loggedInRes = await axios.get(
// "https://mern-auth-template-tutorial.herokuapp.com/auth/loggedIn"
// );
setLoggedIn(loggedInRes.data);
}
useEffect(() => {
getLoggedIn();
}, []);
return (
<AuthContext.Provider value={{ loggedIn, getLoggedIn }}>
{props.children}
</AuthContext.Provider>
);
}
export default AuthContext;
export { AuthContextProvider };
前端 user1.js(这不起作用)
import React, { useContext, useState, useEffect } from 'react'
import Axios from 'axios';
import User from "./User";
export default function User1() {
const [role, setRole] =useState("");
Axios.defaults.withCredentials = true;
useEffect(() => {
Axios.get("http://localhost:5000/auth").then((response) => {
if (response.data.loggedIn == true) {
setRole(response.data.user[0].role);
}
});
}, []);
return (
<div>
{role == "superadmin" && <User/>}
{/* <User/> */}
{role == "admin" && <User/>}
</div>
)
}
用户.js
import React, { Component } from 'react';
import axios from 'axios';
import {
Box,
Heading,
TextInput,
Table,
TableHeader,
TableRow,
TableCell,
Text,
TableBody,
Button,
} from "grommet";
import {
Search,
Edit,
Trash
} from "grommet-icons";
class User extends Component {
constructor(props) {
super(props);
this.state={
users: []
}
}
componentDidMount(){
this.getUsers()
}
getUsers(){
axios.get("http://localhost:5000/auth").then((res) => {
if(res.data.success){
this.setState({
users: res.data.users,
});
console.log("users: ", this.state.users);
}
});
}
onDelete = (id) => {
axios.delete(`http://localhost:5000/auth/delete/${id}`).then((res) => {
alert(res.data.name + " has been deleted successfully");
this.getUsers();
})
};
render() {
return (
<Box className="container">
<Box >
<Box alignSelf="center">
<Heading>All Users</Heading>
</Box>
<Box direction="row" align="center"alignSelf="center" gap="small">
<Search />
<TextInput
className="form-control"
type="search"
placeholder="Search"
name="searchTerm"
onChange={this.handleTextSearch}
></TextInput>
</Box>
</Box>
<Table alignSelf="center">
<TableHeader >
<TableRow>
<TableCell align="center"><Text size="large">#</Text></TableCell >
<TableCell align="center"><Text size="large">Name</Text></TableCell >
<TableCell align="center"><Text size="large">Email</Text></TableCell >
<TableCell align="center"><Text size="large">Password</Text></TableCell >
<TableCell align="center"><Text size="large">Role</Text></TableCell >
<TableCell align="center"><Text size="large">Actions</Text></TableCell >
</TableRow>
</TableHeader>
<TableBody >
{this.state.users.map((user, index) => (
<TableRow>
<TableCell ><Text size="large" >{index}</Text></TableCell>
<TableCell align="center" alignSelf="center" alignContent="center">
<Text size="large">{user.name}</Text>
</TableCell >
<TableCell><Text size="large">{user.email}</Text></TableCell >
<TableCell><Text size="large">{user.passwordHash}</Text></TableCell >
<TableCell><Text size="large">{user.role}</Text></TableCell >
<TableCell gap="xsmall" direction="row">
<Button href="#" onClick={() => this.onDelete(user._id)} color="red">
<Box direction="row" align="center" alignSelf="center" gap="xxsmall">
<Trash color="red" />
<Text size="large">Delete</Text>
</Box>
</Button>
</TableCell >
</TableRow >
))}
</TableBody>
</Table>
<Box width="small" alignSelf="center" >
<Button type="button" color="#99CCFF" href="/register" label="Add New User" ></Button>
</Box>
</Box>
)
}
}
export default User;
解决方案
推荐阅读
- javascript - 使用 Javascript 滚动到特定位置失败
- flutter - 是否有可能获得 Widget 的全球规模?
- flutter - 我可以知道是否有一个颤振包可以在照片和图纸上做标记和注释?
- javascript - 我正在向服务器发送 post 方法但接收 get 方法
- terraform - 如何在 Terraform 资源循环中使用非唯一键创建唯一资源
- windows - 通过远程桌面访问 Amazon EC2 Windows 实例
- error-handling - 由 useQuery 钩子接收到的错误对象不返回正确的错误名称
- sql - ERD - 具有两个主键的递归关系
- android - 向上或向下滚动后 RecyclerView 项目视图更新
- python - 是否有其他方法可以创建一个空数组然后用 Python 填充它?