关于jwt的权限,后端生成及前端解析

303 阅读2分钟

一、服务端(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>
    )
}