Search code examples
next.jscontrollerfetchstrapi

How to get user password from Strapi?


I just don`t know how to fetch that user password in return, so i can make my bcrypt.compare logic on Login Form.

For registration i am used next logic and endpoint:

  • /api/auth/local/register

I`ve tried like:

  • /auth/login + populates + populate deep plugin
  • /api/users/me - which is not returning that password field for security i guess

I guess i need to modify somehow the controllers, and make custom endpoint to take that data from Strapi, but i wasnt find any info related to that, and i wasnt doing that at all.

Wasnt managed to find that info too, cause everybody seems like want to change they password, and i dont kinda need to change it, i just want that hash back, so i can compare it, thats all.

It seems i will be forced to create controller in Strapi, which i can call to validate user password (pass user - he find him - check - response). Because returning password to front in security issue i guess. But then the question, how to create that controller? If you have any suggestions how i can get that password for my logic - i will be glad to see that.

"@strapi/strapi": "^4.21.1",

import { NextResponse } from 'next/server'
import { z } from 'zod'
import isEmail from 'validator/lib/isEmail'
import { comparePassword } from '@/utils/password-compare'
import { Codes } from '@/constants/code-errors'

export async function POST(request) {
  try {
    const { email, password } = await request.json()
    const saltRounds = 10;
    // http://localhost:8080/api/auth/local
    // const response = await fetchBackendAPI({
    //     resource: '/api/admin/login',
    //     method: 'POST',
    //     fields: nonEmptyFields
    //   })

    const emailCheck = z.string().refine(isEmail)

    if (!emailCheck.safeParse(email).success) {
      return NextResponse.json({ message: "Email is incorrect." }, { status: 404 });
    }

    const hashResult = await comparePassword(password, saltRounds)

    if (hashResult !== false) {
      // Save hashed password
    } else {
      // Error handling
    }

    const response = await fetch(`${process.env.REACT_APP_API_ENDPOINT}/api/auth/local`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        identifier: email,
        password: hashResult,
      })
    })

    if (response.ok) {
      console.log("User was logged")
      const newUser = await response.json();
      return NextResponse.json({ newUser }, { status: 200 });
    } else {
      console.log("Response is not ok")
      return NextResponse.json({
        code: response.status,
        message: response.statusText
      }, { status: response.status })
    }

  } catch (err) {
    return NextResponse.json({
      code: Codes.INTERNAL_SERVER_ERROR.code,
      err: Codes.INTERNAL_SERVER_ERROR.message
    }, { status: 500 })
  }
}

UPDATE:

Since i was trying so hard with browsing all info related to my topics, i find official vid on YT like, how to do controllers, this is what i created

    module.exports = {
  routes: [
    {
      method: 'GET',
      path: '/custom',
      handler: 'todo.customAction',
      config: {
        auth: false
      }
    }
  ]
}
    use strict';
    
    /**
     * todo controller
     */
    
    const { createCoreController } = require('@strapi/strapi').factories;
    
    modul

e.exports = createCoreController('api::todo.todo', ({ strapi }) => ({
  async customAction (ctx) {
    try {
      const user = await strapi.query('user', 'users-permissions').findOne({ username: 'Magister4'})
    } catch (err) {
      ctx.body = err
    }
  }
}))

And this is kinda worked, but i wasn`t able to find, return, or change password. It seems todo.todo have no access to main users-permissions stuff.


Solution

  • To generate a new controller in a new API, you can just run "yarn strapi generate" in your Strapi project.

    Then just uncomment the route and controller.

    Then use that line to get the user data

    await strapi.db.query('plugin::users-permissions.user').findOne({
      where: { email: email }
    })
    

    Set the new route Public to be able to access it without being authorized.

    Here is the process in a video I made for you: https://www.loom.com/share/cf60dafff14840c886c6d222530f557b