redux 使用JWT令牌的注册过程,并在令牌过期时发出

baubqpgj  于 2023-11-19  发布在  其他
关注(0)|答案(2)|浏览(95)

所以basicall我想创建一个注册过程中,你给给予你的用户名,电子邮件(但它不能存在于数据库中),密码,然后确认密码。项目是在nextJS与网页路由器和 typescript 。

import React, { useState } from 'react'
import styles from './styles.module.css'
import { Header } from '@/components'
import Head from 'next/head'
import { hash } from '@/scripts/hashing'
import axios from 'axios'
import { getTokens } from '@/scripts/tokens'
import { store } from '@/redux/store'
import Link from 'next/link'
import { useDispatch } from 'react-redux'
import { setAccessToken, setRefreshToken } from '@/redux/constants/jwtTokensReducer'

const Register = () => {
  const [name, setName] = React.useState('')
  const [email, setEmail] = useState('')
  const [emailExists, setEmailExists] = useState(false)
  const [password, setPassword] = useState('')
  const [repeatedPassword, setRepeatedPassword] = useState('')
  const [passwordsMatch, setPasswordsMatch] = useState(true)
    const dispatch = useDispatch()
    const checkEmailExists =async () => {
        if(email) {
            await getTokens(dispatch)
            console.log(store.getState().jwtTokens.accessToken)
            await axios.get(`${process.env.API_URL}/api/email=${email}`, {
                headers: {
                    token: store.getState().jwtTokens.accessToken,
                }
            }).then(res => {
                if(res.data !== null) {
                    setEmailExists(true)
                } else {
                    setEmailExists(false)
                }
            })
        } else {
            setEmailExists(false)
        }
    }
    const checkPasswordsMatch =async () => {
        // this function compares passwords and works as expected
    }

    const register =async (e:any) => {
        e.preventDefault()
        checkEmailExists()
        checkPasswordsMatch()
        console.log(emailExists)
        if(!emailExists && passwordsMatch) {
            const hashedPass = await hash(password)
            console.log('Hashed Password:', hashedPass)
            const restaurant = {
                name: name,
                email: email,
                email_confirmed: false,
                password: hashedPass,
                created: `${new Date().getDay()}.${new Date().getMonth()}.${new Date().getFullYear()}`,
                cuisineType: cuisineType,
                address: address,
                phoneNumber: phoneNumber,
                priceRange: priceRange,
            }
            console.log('aaa')
            await getTokens(dispatch)
            // const accessToken = await axios.post(`${process.env.API_URL}/api/web/jwt-action`, {
            //     accessToken: store.getState().jwtTokens.accessToken,
            //     refreshToken: store.getState().jwtTokens.refreshToken,
            //   })
            console.log(store.getState().jwtTokens.accessToken)
            console.log('bbb')
            axios.post(`${process.env.API_URL}/api/restaurants/register`, {
                restaurant: restaurant
            }, { headers: { token: store.getState().jwtTokens.accessToken,}}).then(() => console.log('registered'))
        }
    }
    return (
        <>
            <Head>
                <title>Registration</title>
            </Head>
            <div className={`${styles.main}`}>
                <Header />
                <div className={`${styles.Registration}`}>
                    <p className={`${styles.RegistrationTitle}`}>Register</p>
                    <form className={`${styles.RegistrationForm}`} onSubmit={register}}>
                        <div className={`${styles.RegistrationReg_LogBox}`}>
                            <Link href={`/login`} className={`${styles.RegistrationLogBox}`}>Login</Link>
                            <Link href={`/registration`} className={`${styles.RegistrationRegBox}`}>Register</Link>
                        </div>
                        <div>
                            <input className={`${styles.RegistrationInput}`}
                            type='text' onChange={e => setName(e.target.value)} placeholder='Restaurant name*' required/>
                        </div>
                        <div>
                            <input className={`${styles.RegistrationInput}
                            ${emailExists && styles.RegistrationWarn}`}
                            type='email' onChange={e => setEmail(e.target.value)} placeholder='email*'
                            onFocus={() => setEmailExists(false)} onBlur={checkEmailExists} required/>
                            {emailExists && <p className={`${styles.RegistrationErrorText}`}>Email is already used</p>}
                        </div>
                        <div>
                            <input className={`${styles.RegistrationInput} ${!passwordsMatch && styles.RegistrationWarn}`}
                            type='password' autoComplete='new-password' onChange={e => setPassword(e.target.value)} placeholder='password*' onBlur={checkPasswordsMatch} onFocus={() => setPasswordsMatch(true)} required minLength={8}/>
                            <p className={`${styles.RegistrationInfoText}`}>Passwords needs to be at least 8 char long</p>
                        </div>
                        <div>
                            <input className={`${styles.RegistrationInput} ${!passwordsMatch && styles.RegistrationWarn}`}
                            type='password' autoComplete='new-password' onChange={e => setRepeatedPassword(e.target.value)} placeholder='confirm password*' onBlur={checkPasswordsMatch} onFocus={() => setPasswordsMatch(true)} required minLength={8}/>
                            {!passwordsMatch && <p className={`${styles.RegistrationErrorText}`}>Passwords needs to match</p>}
                        </div>
                        <button type='submit' className={`${styles.RegistrationSubmitButton}`}>Register</button>
                        <p className={`${styles.RegistrationFormNoAccount}`}>Already have an account? <span className={`${styles.RegistrationFormHighlightedText}`}>
                            <Link href={`/login`}>Login now</Link></span></p>
                    </form>
                </div>
            </div>
        </>
    )
}

export default Register

字符串
还有一个函数getTokens()

import axios from 'axios'
import { setAccessToken, setRefreshToken } from '@/redux/constants/jwtTokensReducer'
import { store } from '@/redux/store'
import { hash } from '@/scripts/hashing'
import { encrypt } from './encryption'
import { Dispatch } from 'redux'

export const getTokens = async (dispatch: Dispatch) => {
    axios.post(`${process.env.API_URL}/api/web/jwt-action`, {
      accessToken: store.getState().jwtTokens.accessToken,
      refreshToken: store.getState().jwtTokens.refreshToken,
    })
      .then(data => {
        if(data.data.accessToken) {
          dispatch({type: setAccessToken, payload: data.data.accessToken})
        }
        if(data.data.refreshToken) {
          dispatch({type: setRefreshToken, payload: data.data.refreshToken})
        }
      })
}


我想解决的问题是,令牌的有效期为15 m,这意味着如果用户在页面上的时间超过15 m,然后提交表单,它就不会将他注册到应用程序,所以我想在register()中调用getTokens(),并在发送post请求到/registration之前执行它。我尝试过类似于alphanc await的东西,但它没有帮助。
如果你能帮我,你能不能稍后再看看这个问题,还有两个与这个注册相关的问题?

holgip5t

holgip5t1#

您需要useSelector来检索dispatch之后更新的值。

const Register = () => {
    // place this above your register method
    const { accessToken } = useSelector((state) => state.jwtTokens);

    const register = async (e: any) => {
        // rest of your code

        await getTokens(dispatch);

        console.log(accessToken); // this should give you the updated values

    }
}

字符串

djp7away

djp7away2#

getTokens被声明为async,但它在返回之前不会等待任何解决。我怀疑register回调的其余部分在访问/刷新令牌更新状态之前正在运行/完成。
async/await与Promise链混合使用也是一种反模式,选择其中一个。
async/await

export const getTokens = async (dispatch: Dispatch) => {
  const state = store.getState();
  const { jwtTokens: { accessToken, refreshToken } } = state;

  try {
    const { data } = await axios.post(
      `${process.env.API_URL}/api/web/jwt-action`,
      { accessToken, refreshToken },
    );

    if (data.accessToken) {
      dispatch({ type: setAccessToken, payload: data.accessToken });
    }
    if (data.refreshToken) {
      dispatch({ type: setRefreshToken, payload: data.refreshToken });
    }
  } catch(error) {
    // catch and handle/ignore
  }
};

字符串
Promise链

export const getTokens = (dispatch: Dispatch) => {
  const state = store.getState();
  const { jwtTokens: { accessToken, refreshToken } } = state;

  // Return Promise that can be awaited
  return axios.post(
    `${process.env.API_URL}/api/web/jwt-action`,
    { accessToken, refreshToken },
  )
    .then(({ data }) => {
      if (data.accessToken) {
        dispatch({ type: setAccessToken, payload: data.accessToken });
      }
      if (data.refreshToken) {
        dispatch({ type: setRefreshToken, payload: data.refreshToken });
      }
    })
    .catch(error => {
      // catch and handle/ignore
    });
};

相关问题