Home > Blockchain >  NEXT JS AND MONGODB JWT integration
NEXT JS AND MONGODB JWT integration

Time:02-05

Looking for a backend dev that can simply help me implement MONGODB with nextJS and the current model I have now. I have bought https://www.devias.io admin dashboard, and just want to implement auth and database reading with it.

Just want the basic auth setup. It's already setup in the FILES just wanting to know how to configure it properly based on the devias guides

Has anyone done this before I can't find any documentation on it It's setup with mock data at the moment

SRC/API/AUTH/index.js

import { createResourceId } from '../../utils/create-resource-id';
import { decode, JWT_EXPIRES_IN, JWT_SECRET, sign } from '../../utils/jwt';
import { wait } from '../../utils/wait';
import { users } from './data';

class AuthApi {
  async signIn(request) {
    const { email, password } = request;

    await wait(500);

    return new Promise((resolve, reject) => {
      try {
        // Find the user
        const user = users.find((user) => user.email === email);

        if (!user || (user.password !== password)) {
          reject(new Error('Please check your email and password'));
          return;
        }

        // Create the access token
        const accessToken = sign({ userId: user.id }, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });

        resolve({ accessToken });
      } catch (err) {
        console.error('[Auth Api]: ', err);
        reject(new Error('Internal server error'));
      }
    });
  }

  async signUp(request) {
    const { email, name, password } = request;

    await wait(1000);

    return new Promise((resolve, reject) => {
      try {
        // Check if a user already exists
        let user = users.find((user) => user.email === email);

        if (user) {
          reject(new Error('User already exists'));
          return;
        }

        user = {
          id: createResourceId(),
          avatar: undefined,
          email,
          name,
          password,
          plan: 'Standard'
        };

        users.push(user);

        const accessToken = sign({ userId: user.id }, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });

        resolve({ accessToken });
      } catch (err) {
        console.error('[Auth Api]: ', err);
        reject(new Error('Internal server error'));
      }
    });
  }

  me(request) {
    const { accessToken } = request;

    return new Promise((resolve, reject) => {
      try {
        // Decode access token
        const { userId } = decode(accessToken);

        // Find the user
        const user = users.find((user) => user.id === userId);

        if (!user) {
          reject(new Error('Invalid authorization token'));
          return;
        }

        resolve({
          id: user.id,
          avatar: user.avatar,
          email: user.email,
          name: user.name,
          plan: user.plan
        });
      } catch (err) {
        console.error('[Auth Api]: ', err);
        reject(new Error('Internal server error'));
      }
    });
  }
}

export const authApi = new AuthApi();

then /SRC/API/AUTH/data.js

export const users = [
  {
    id: '5e86809283e28b96d2d38537',
    avatar: '/assets/avatars/avatar-anika-visser.png',
    email: '[email protected]',
    name: 'Anika Visser',
    password: 'Password123!',
    plan: 'Premium'
  }
];

This is the documentation on it

JSON Web Token (JWT)

Most auth providers use this strategy under the hood to provide access tokens. Currently, the app doesn't cover the backend service, and this service is mocked (faked) using http client interceptors. The implementation is basic, but enough to give you a starting point.

How it was implemented

Since tokens are meant to be created on the backend server, they are built with encrypt, encode and decode utility methods because they are not meant to be used on the client. These utilities can be found in src/utils/jwt. These are for development purposes only, and you must remove (or avoid using) them.

How to use JWT Provider

The app is delivered with JWT Provider as default auth strategy. If you changed or removed it, and you want it back, simply follow these steps:

  • Step 1: Import the provider

Open src/pages/_app.js file, import the provider and wrap the App component with it.

// src/pages/_app.js
import { AuthConsumer, AuthProvider } from '../contexts/auth/jwt-context';

const App = (props) => {
  const { Component, pageProps } = props;
    
  return (
    <AuthProvider>
      <Component {...pageProps} />
    </AuthProvider>
  );
};
  • Step 2: Set the hook context

Open src/hooks/use-auth.js file and replace the current context the following line:

import { AuthContext } from '../contexts/auth/jwt-context';

How to use auth

Retrieve user profile

In the example below, you can find how it can be used in any component not just the App. Should you want to use it in any other component, you'll have to import the useAuth hook and use it as needed.

// src/pages/index.js
import { useAuth } from '../hooks/use-auth';

const Page = () => {
  const { user } = useAuth();

  return (
    <div>
      Email: {user.email}
    </div>
  );
};

Auth methods / actions

For simplicity and space limitations, the code below is used only to exemplify, actual code can be found in the components.

// src/pages/index.js
import { useAuth } from '../hooks/use-auth';

const Page = () => {
  const { login } = useAuth();
  
  const handleLogin = () => {
    // Email/username and password
    login('[email protected]', 'Password123!');
  };
s
  return (
    <div>
      <button onClick={handleLogin}>
        Login
      </button>
    </div>
  );
};

Implemented flows

Currently, the app only covers the main flows:

  • Register
  • Login
  • Logout

CodePudding user response:

const mongoose = require('mongoose');
const jwt = require("jsonwebtoken");

// Connect to MongoDB
mongoose.connect('mongodb://localhost/yourdbname', {
    useNewUrlParser: true,
    useUnifiedTopology: true
});

const userSchema = new mongoose.Schema({
        id: {
            type: String,
            required: true,
            unique: true
        },
        email: {
            type: String,
            required: true
        },
        name: {
            type: String,
            required: true
        },
        password: {
            type: String,
            required: true
        },
        plan: {
            type: String,
        default:
            'Standard'
        },
        avatar: {
            type: String,
        default:
            null
        },
    });

const User = mongoose.model('User', userSchema);

const JWT_SECRET = process.env.JWT_SECRET;
const JWT_EXPIRES_IN = '7d';

class AuthApi {
    async signIn(request) {
        const {
            email,
            password
        } = request;

        const user = await User.findOne({
                email
            });
        if (!user || (user.password !== password)) {
            throw new Error('Please check your email and password');
        }

        const accessToken = jwt.sign({
                userId: user.id
            }, JWT_SECRET, {
                expiresIn: JWT_EXPIRES_IN
            });

        return {
            accessToken
        };
    }

    async signUp(request) {
        const {
            email,
            name,
            password
        } = request;

        const existingUser = await User.findOne({
                email
            });
        if (existingUser) {
            throw new Error('User already exists');
        }

        const newUser = new User({
                id: mongoose.Types.ObjectId(),
                email,
                name,
                password,
                plan: 'Standard',
                avatar: null,
            });

        await newUser.save();

        const accessToken = jwt.sign({
                userId: newUser.id
            }, JWT_SECRET, {
                expiresIn: JWT_EXPIRES_IN
            });

        return {
            accessToken
        };
    }

    async me(request) {
        const {
            accessToken
        } = request;

        const decoded = jwt.verify(accessToken, JWT_SECRET);
        const {
            userId
        } = decoded;

        const user = await User.findById(userId);
        if (!user) {
            throw new Error('Invalid authorization token');
        }

        return {
            id: user.id,
            avatar: user.avatar,
            email: user.email,
            name: user.name,
            plan: user.plan
        };
    }
}

export const authApi = new AuthApi();
  • Related