简体   繁体   English

我有授权问题,我可以登录并将刷新令牌发送到 cookie 和数据库,但无法使用 axios 将访问令牌保存到 header

[英]I have issues with authorization, I am able to login and send the refresh token to cookie and db but cannot save access token to header using axios

I have issues with authorization, I am able to login and send the refresh token to cookie and db but cannot save access token to header using axios. The authorization does not show at all when I check the.network in my browser.我有授权问题,我可以登录并将刷新令牌发送到 cookie 和数据库,但无法使用 axios 将访问令牌保存到 header。当我在浏览器中检查 .network 时,授权根本不显示。 I tried to make the header persist using axios.default.headers but nothing.我尝试使用 axios.default.headers 使 header 持续存在,但什么也没有。

Also when I console.log(axios.defaults.headers.common) after setting axios.defaults.headers.common['Authorization'] = Bearer ${token} I see the token in the console but doesn't appear in the request header in the browser.此外,当我在设置axios.defaults.headers.common['Authorization'] = Bearer ${token}后使用console.log(axios.defaults.headers.common)我在控制台中看到了令牌,但未出现在请求中header 在浏览器中。

export default function Login () {
  const [state, setState] = useContext(UserContext);
  const navigate = useNavigate()

  const { register, handleSubmit, formState: { errors } } = useForm<Inputs>({
    defaultValues: loginValues,
    mode: 'onTouched',
    criteriaMode: 'firstError',
    reValidateMode: 'onBlur'
  });

  const onSubmit: SubmitHandler<Inputs> = async (data) => {
    try {
      const phone_num = data.phone_num; // eslint-disable-line
      const password = data.password;

      const { data: login } = await axios.post("auth/login_admin", {
        phone_num,
        password
      },
      { withCredentials: true }
      );

      axios.defaults.headers.common['Authorization'] = `Bearer ${login['token']}`;

      setState({
        data: {
          id: login.data.id,
          isAdmin: login.data.isAdmin,
          user_type: login.data.user_type
        },
        loading: false,
        error: null
      })

      navigate("/council");
    } catch (err: any) {
      setState({
        data: null,
        loading: false,
        error: err.message
      })
      console.log(err)
    }
  };

  return (
    <>
      <Box
        sx={{
          display: 'center',
          justifyContent: 'center',
          alignItems: 'center',
          width: '100vw',
          height: '100vh'
        }}
      >
        <Box
          sx={{
            height: 'auto',
            width: '40%',
            display: 'center',
            justifyContent: 'center',
            alignItems: 'center'
          }}
          component='form'
        >
          <TextField
            margin="normal"
            fullWidth
            variant='filled'
            id="phone_num"
            label="Phone Number"
            {...register("phone_num", {
              required: 'Phone Number is required',
              pattern: {
                value: phonePattern,
                message: 'Please enter a valid phone number'
              }
            })}
            autoFocus
            error={!!errors?.phone_num}
          />
          {errors.phone_num &&
              (<Typography variant='body2' mt={1}
              component='span' sx={{ color: 'red', textAlign: 'left' }}
              >{errors.phone_num?.message}</Typography>)
          }
          <FormControl sx={{ mt: 3, width: '100%' }} variant="filled">
            <InputLabel htmlFor="filled-adornment-password">Password</InputLabel>
            <FilledInput
              id="filled-adornment-password"
              // type={passType}
              {...register("password", {
                required: 'Password is required',
                pattern: {
                  value: passwordPattern,
                  message: 'Password cannot be less than 8 characters
                }
              })}
              error={!!errors?.password}
            />
          </FormControl>
          <Button
            type="submit"
            onClick={handleSubmit(onSubmit)} // eslint-disable-line
          >
            Sign In
          </Button>
        </Box>
      </Box>
    </>
  )
}

AND THIS IS THE API: This is my api I use Nodejs这是 API:这是我的 api 我使用 Nodejs

SERVICE:服务:

export const adminLogin = async (res: Response, body: AuthType, next: NextFunction) => {
  let transaction;
  try {
    transaction = await sequelize.transaction();
    const { phone_num, password } = body;
    const user = await Admin.findOne({ where: { phone_num } }, { transaction });
    if (!user || user === null) {
      return next(new AppError("Invalid phone number or password", BAD_REQUEST));
    }

    const isMatch = verifyBcryptPassword(password, user.password);
    if (!isMatch) {
      return next(new AppError("Invalid phone number or password", BAD_REQUEST));
    }

    await transaction.commit();
    const { token, refreshToken } = await jwtGenerator(user.dataValues);

    res.cookie('refreshToken', refreshToken, {
      httpOnly: true,
      maxAge: 7 * 24 * 60 * 60 * 1000 //7 days
    });

    return { user, token };
  } catch (e: any) {
    if (transaction) {
      await transaction.rollback();
    }
    return next(new AppError(e, BAD_REQUEST));
  }
};

CONTROLLER: CONTROLLER:

const login_admin = async (req: Request, res: Response, next: NextFunction) => {
  try {
    const validate = authValidator.authLogin(req.body);
    if (validate.error) {
      return next(new AppError(validate.error.message, BAD_REQUEST));
    }

    const result = await adminLogin(res, req.body, next);
    const user = result?.user.dataValues;
    const access = result?.token;

    return res.status(OK).json({
        status: "success",
        message: "Login was successful.",
        token: access,
        data: {
          id: user.id,
          isAdmin: user.isAdmin,
          user_type: user.user_type
        }
      });
  } catch (error: any) {
    return next(new AppError(error.message, BAD_REQUEST));
  }
};

I think you should return the Bearer token directly in the response body, then you can use it with axios like that:我认为您应该直接在响应正文中返回 Bearer 令牌,然后您可以像这样将它与 axios 一起使用:

axios.get(YOUR_URL, {
    headers: {
        Authorization: `Bearer ${YOUR_TOKEN}`
    }
}).then((res: AxiosResponse) => {
    // Do some success stuff
}).catch((err: AxiosError) => {
    // Handle error
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM