Home  >  Article  >  Web Front-end  >  Authentication with JWT on Frontend and Backend: Implementing with Node.js and ReactJS (in TypeScript)

Authentication with JWT on Frontend and Backend: Implementing with Node.js and ReactJS (in TypeScript)

Barbara Streisand
Barbara StreisandOriginal
2024-11-01 15:18:02574browse

Autenticação com JWT no Frontend e Backend: Implementando com Node.js e ReactJS (em TypeScript)

Authentication via JSON Web Token (JWT) is widely used to secure APIs and ensure that only authorized users can access certain data. In this post, we will show you how to configure JWT on the backend with Node.js and on the frontend with ReactJS using TypeScript, from token generation to secure user session management.

Configuring the Backend with Node.js

First, let's create an API with Node.js, Express and TypeScript that generates and validates JWT tokens.

Step 1: Configuring the Environment

Create a new project and install the main dependencies:

npm init -y
npm install express jsonwebtoken bcryptjs dotenv
npm install -D typescript @types/node @types/express @types/jsonwebtoken @types/bcryptjs ts-node

Create a tsconfig.json file for TypeScript configuration:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "./dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

Step 2: Structuring the Backend

Create a simple structure, starting with a server.ts file and a routes folder to organize authentication routes.

server.ts

import express, { Application } from 'express';
import dotenv from 'dotenv';
import authRoutes from './routes/authRoutes';

dotenv.config();

const app: Application = express();
app.use(express.json());

app.use('/api/auth', authRoutes);

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Servidor rodando na porta ${PORT}`));

routes/authRoutes.ts

Create a file for authentication routes. Here we will have a login route that will validate the user and return the JWT token.

import express, { Request, Response } from 'express';
import jwt from 'jsonwebtoken';
import bcrypt from 'bcryptjs';

const router = express.Router();

// Simulação de banco de dados
const users = [{ username: 'usuario', password: 'senha123' }];

router.post('/login', async (req: Request, res: Response) => {
    const { username, password } = req.body;
    const user = users.find(u => u.username === username);

    if (!user || !(await bcrypt.compare(password, user.password))) {
        return res.status(401).json({ message: 'Credenciais inválidas' });
    }

    const token = jwt.sign({ username }, process.env.JWT_SECRET as string, { expiresIn: '1h' });
    res.json({ token });
});

export default router;

Step 3: Securing Routes with Middleware

Add middleware to protect routes that require authentication.

middleware/authMiddleware.ts

import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';

interface JwtPayload {
    username: string;
}

export const authMiddleware = (req: Request, res: Response, next: NextFunction): void => {
    const token = req.headers['authorization'];
    if (!token) {
        res.status(403).json({ message: 'Token não fornecido' });
        return;
    }

    jwt.verify(token, process.env.JWT_SECRET as string, (err, decoded) => {
        if (err) {
            res.status(401).json({ message: 'Token inválido' });
            return;
        }
        req.user = decoded as JwtPayload;
        next();
    });
};

Configuring the Frontend with ReactJS

On the frontend, we will use React to handle authentication, sending credentials, and storing the JWT token.

Step 1: Configuring the Login Interface

First, create a Login.tsx component to capture the user's credentials and send a login request to the backend.

Login.tsx

import React, { useState } from 'react';
import axios from 'axios';

const Login: React.FC = () => {
    const [username, setUsername] = useState<string>('');
    const [password, setPassword] = useState<string>('');
    const [error, setError] = useState<string>('');

    const handleLogin = async (e: React.FormEvent) => {
        e.preventDefault();
        try {
            const response = await axios.post('/api/auth/login', { username, password });
            localStorage.setItem('token', response.data.token);
            window.location.href = '/dashboard';
        } catch (err) {
            setError('Credenciais inválidas');
        }
    };

    return (
        <form onSubmit={handleLogin}>
            <input
                type="text"
                placeholder="Username"
                value={username}
                onChange={(e) => setUsername(e.target.value)}
            />
            <input
                type="password"
                placeholder="Password"
                value={password}
                onChange={(e) => setPassword(e.target.value)}
            />
            <button type="submit">Login</button>
            {error && <p>{error}</p>}
        </form>
    );
};

export default Login;

Step 2: Protect Routes in the Frontend

Create a function for protected routes, using the JWT token to access the API.

PrivateRoute.tsx

import React from 'react';
import { Route, Redirect, RouteProps } from 'react-router-dom';

interface PrivateRouteProps extends RouteProps {
    component: React.ComponentType<any>;
}

const PrivateRoute: React.FC<PrivateRouteProps> = ({ component: Component, ...rest }) => (
    <Route
        {...rest}
        render={(props) =>
            localStorage.getItem('token') ? (
                <Component {...props} />
            ) : (
                <Redirect to="/login" />
            )
        }
    />
);

export default PrivateRoute;

Step 3: Send the JWT Token in Requests

Configure axios to automatically include the JWT token in protected requests.

axiosConfig.ts

import axios from 'axios';

const token = localStorage.getItem('token');
if (token) {
    axios.defaults.headers.common['Authorization'] = token;
}

export default axios;

Step 4: Example of Usage with a Protected Route

Now, create an example of a protected page that requires the token to access.

Dashboard.tsx

import React, { useEffect, useState } from 'react';
import axios from './axiosConfig';

const Dashboard: React.FC = () => {
    const [data, setData] = useState<string>('');

    useEffect(() => {
        const fetchData = async () => {
            try {
                const response = await axios.get('/api/protected');
                setData(response.data.message);
            } catch (error) {
                console.error(error);
            }
        };
        fetchData();
    }, []);

    return <h1>{data || 'Carregando...'}</h1>;
};

export default Dashboard;

Conclusion

With these steps, we set up full JWT authentication in TypeScript for a project that uses Node.js on the backend and React on the frontend. This approach is highly secure, efficient and widely adopted to protect modern applications.

The above is the detailed content of Authentication with JWT on Frontend and Backend: Implementing with Node.js and ReactJS (in TypeScript). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn