Authentication with JWT Metronic8 React API recommendation

the documentation at https://preview.keenthemes.com/theme-api/api/documentation to my knowledge has no security and only a user route.

I am looking for recommendations on how to integrate an authentication API changing the REACT_APP_API_URL in .env but with the features:
- JWT
- /register check that email not already exist
- hash and salt passwords
- security, like can not list users with GET /users lol

Really struggling to even get the login to work

Prefer stack React + Node.js Express + MySQL/PostgreSQL

Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(

Replies (3)

Hi,

Our API doesn't have anything to verify the user's authentication and currently auth routes are on different API, we are planning to migrate to one main API with authentication and user crud, these API will be available in the next releases with the source code.

At the moment we haven't tried using our React application with Node.js, we will try this and consider implementing the same tech stack in upcoming future.

For now to implement authentication you can refer to one of the tutorials below.

https://towardsdev.com/jwt-authentication-with-node-js-and-react-dc41ef0e6136

https://www.bezkoder.com/react-express-authentication-jwt/

https://medium.com/@romanchvalbo/how-i-set-up-react-and-node-with-json-web-token-for-authentication-259ec1a90352

Regards,
Lauris Stepanovs,
Keenthemes Support Team

I actually got an express version working but after trying to integrate the user_id and google authentication have given up for the time being and just using PHP again.

Here is the script for yours or anyone elses benefit:

const express = require('express')
const cors = require('cors')
const bcrypt = require('bcrypt')
const jwt = require('jsonwebtoken')
const Sequelize = require('sequelize')
require('dotenv').config()
const PORT = 5050

// Initialize the express app
const app = express()

// Enable CORS
app.use(cors())

// parse application/x-www-form-urlencoded
app.use(express.urlencoded({extended: true}))

// parse application/json
app.use(express.json())

// Connect to the database
const sequelize = new Sequelize(process.env.DB_NAME, process.env.DB_USER, process.env.DB_PASSWORD, {
host: process.env.DB_HOST,
dialect: 'mysql',
define: {
underscored: true,
},
})

// Define the User model
const Users = sequelize.define('users', {
id: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
},
google_id: {
type: Sequelize.STRING,
},
google_token: {
type: Sequelize.STRING,
},
email: {
type: Sequelize.STRING,
unique: true,
},
password: {
type: Sequelize.STRING,
},
fullname: {
type: Sequelize.STRING,
},
created_at: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
},
updated_at: {
type: Sequelize.DATE,
defaultValue: Sequelize.NOW,
},
})

app.post('/register', async (req, res) => {
try {
// Extract email, password, and other user details from the request body
const {email, password, first_name, last_name} = req.body
// Check if a user with the same email already exists
const existingUser = await Users.findOne({where: {email: email}})
if (existingUser) {
return res.status(400).json({message: 'A user with this email already exists'})
}

// Hash the user's password
const hashedPassword = await bcrypt.hash(password, 10)

// Create a new user in the database
const newUser = await Users.create({
email: email,
password: hashedPassword,
first_name: first_name,
last_name: last_name,
})

// Generate a JSON web token with the user's id and a secret key
const api_token = jwt.sign({id: newUser.id}, process.env.JWT_SECRET)

// Return the JSON web token and a status code of 201 Created
return res.status(201).json({api_token})
} catch (error) {
console.error(error)
// Return a 500 Internal Server Error if there is any error while creating the user
return res.status(500).json({message: 'Error creating user. Please try again later.'})
}
})

app.post('/login', async (req, res) => {
// Extract email, and password from the request body
const {email, password} = req.body

try {
// Find the user with the same email in the database
const user = await Users.findOne({where: {email: email}})
// Return a 401 Unauthorized if the user with the email is not found or if the password is invalid
if (!user || !bcrypt.compareSync(password, user.password)) {
return res.status(401).json({message: 'Invalid email or password'})
}

// Generate a JSON web token with the user's id and a secret key
const api_token = jwt.sign({id: user.id}, process.env.JWT_SECRET)

// Return the JSON web token and a status code of 200 OK
return res.status(200).json({api_token})
} catch (error) {
console.error(error)
// Return a 500 Internal Server Error if there is any error while logging in
return res.status(500).json({message: 'Error logging in. Please try again later.'})
}
})

app.post('/verify_token', async (req, res) => {
// Extract token from the request body
const {api_token} = req.body
try {
// Verify the token with a secret key
const decoded = jwt.verify(api_token, process.env.JWT_SECRET)
const user = await Users.findOne({where: {id: decoded.id}})
if (!user) {
return res.status(401).json({message: 'Invalid token'})
}
return res.status(200).json({user})
} catch (error) {
console.error(error)
// Return a 401 Unauthorized if the token is invalid or expired
return res.status(401).json({message: 'Invalid token'})
}
})

app.use((req, res) => {
res.status(404).json({message: 'Not found'})
})

app.listen(PORT, () => {
console.log('Server is running on port ${PORT}.')
})

Hi,

Thank you for sharing with us your code. This should be useful for our Node.js developers.

Regards,
Lauris Stepanovs,
Keenthemes Support Team

Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(
Text formatting options
Submit
Here's a how to add some HTML formatting to your comment:
  • <pre></pre> for JS codes block
  • <pre lang="html"></pre> for HTML code block
  • <pre lang="scss"></pre> for SCSS code block
  • <pre lang="php"></pre> for PHP code block
  • <code></code> for single line of code
  • <strong></strong> to make things bold
  • <em></em> to emphasize
  • <ul><li></li></ul>  to make list
  • <ol><li></li></ol>  to make ordered list
  • <h3></h3> to make headings
  • <a></a> for links
  • <img> to paste in an image
  • <blockquote></blockquote> to quote somebody
  • happy  :)
  • shocked  :|
  • sad  :(