一、服务端(express)
1、引入
import jwt from 'jsonwebtoken';
import { expressjwt } from 'express-jwt';
2、生成 alice 的角色是 admin
const token = jwt.sign({
name: "alice",
role: "admin"
}, 'hello', { algorithm: 'none' });
3、解析 token
app.use(expressjwt({
secret: secretKey,
algorithms: ["HS256"]
}).unless({
path: [
'/',
'/api/account/login'
] //除了这个地址,其他的URL都需要验证
}));
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
if (err.name === "UnauthorizedError") {
res.status(401).json({
success: false,
message: 'invalid token...'
});
} else {
next(err);
}
});
app.get('/', (req: Request, res: Response) => {
res.send('hello~');
});
app.post('/api/account/profile', (req: any, res: Response) => {
res.json(req?.auth);
});
4、服务端全部代码
import bodyParser from 'body-parser';
import express, { Express, Request, Response, NextFunction } from 'express';
import { expressjwt } from 'express-jwt';
import jwt from 'jsonwebtoken';
import JSONdb from 'simple-json-db';
const db = new JSONdb('storage.json');
const app: Express = express();
const port = process.env.PORT || 8000;
const secretKey = 'hello';
app.use(bodyParser.json());
app.use(expressjwt({
secret: secretKey,
algorithms: ["HS256"]
}).unless({
path: [
'/',
'/api/account/login'
] //除了这个地址,其他的URL都需要验证
}));
app.use((err: any, req: Request, res: Response, next: NextFunction) => {
if (err.name === "UnauthorizedError") {
res.status(401).json({
success: false,
message: 'invalid token...'
});
} else {
next(err);
}
});
app.get('/', (req: Request, res: Response) => {
res.send('hello~');
});
app.post('/api/account/profile', (req: any, res: Response) => {
res.json(req?.auth);
});
app.get('/init', (req: Request, res: Response) => {
db.set('alice', {
password: '123456',
role: 'admin'
});
db.set('bob', {
password: '123456',
role: 'user'
});
res.send('ok');
});
app.post('/api/account/login', (req: Request, res: Response) => {
const { username, password } = req.body;
if (db.has(username)) {
const { password: p, role } = db.get(username);
if (password === p) {
const token = jwt.sign({
name: username,
role: role
}, secretKey, { algorithm: 'HS256' });
res.json({ success: true, token: token, message: 'login success' });
} else {
res.json({ success: false, token: null, message: 'password is error' });
}
} else {
res.json({ success: false, token: null, message: 'username is not exist' });
}
});
app.listen(port, () => {
console.log(`⚡️[server]: Server is running at https://localhost:${port}`);
});
二、客户端(react)
1、引用 jwt-claims
var decode = require('jwt-claims');
2、得到权限 (前提条件:登录成功后获得了token)
if (token) {
const claims = decode(token);
console.log('claims', claims);
setRole(claims?.role);
}
3、客户端代码:
import { Button, Card, Form, Input, message} from "antd";
import { LockOutlined, UserOutlined } from "@ant-design/icons";
var decode = require('jwt-claims');
export default () => {
const [requesting, setRequesting] = useState<boolean>(false);
return (
<Card>
<Form
name="basic"
onFinish={async ({ username, password }) => {
setRequesting(true);
const res: any = await fetch(
`/api/account/login`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
username: username,
password: password
})
}
);
if (res.status === 200) {
const { success, message: msg, token }: any = await res.json();
if (success) {
message.success(msg);
const claims = decode(token);
const { role } = claims;// 这里就得到了登录用户的权限
navigate('/');
} else {
message.error(msg);
}
} else {
message.error('api 发生一个错误')
}
setRequesting(false);
}}
autoComplete="off"
>
<Form.Item
name="username"
rules={[{ required: true, message: 'Please input your name!' }]}
>
<Input prefix={<UserOutlined />} placeholder={t('username')} />
</Form.Item>
<Form.Item
name="password"
rules={[{ required: true, message: 'Please input your password!' }]}
>
<Input.Password prefix={<LockOutlined />} placeholder={t('password')} />
</Form.Item>
<Form.Item>
<Button loading={requesting} disabled={requesting} type="primary" htmlType="submit">
Login
</Button>
</Form.Item>
</Form>
</Card>
)
}